2016년 5월 27일 금요일

AppLocker 사용법

administrators 를 제외하고 다른 일반 사용자에 대해서는 프로그램 실행 제한을 하려고 알아보다, AppLocker 란걸로 가능하단 걸 알게 됐다.

원하는 대로 잘 되지 않아 찾아 보니 기본적으로 아래와 같았다.

  1. 규칙이 없으면 해당 파일 형식의 모든 파일을 실행할 수 있다.

  2. 특정 규칙 컬렉션에 대한 AppLocker 규칙이 만들어져 있으면 규칙에서 명시적으로 허용된 파일만 실행할 수 있습니다.


그래서 규칙을 만들 때, 반드시 administrators 는 모든 파일을 사용가능 하게끔 같이 넣어줘야 한다. 그렇지 않으면 정책자체를 수정 할 수 없게 된다.

실행파일규칙에서 우클릭을 하면, 기본규칙 만들기를 클릭하면
Administrators 모든파일, Everyone Windows 폴더 모든파일, Everyone Program Files 폴더 모든 파일'이 생성 된다.

다른 규칙은 문제가 안되는 데, Everyone Windows 폴더 모든파일 규칙을 삭제 하면 원격 접속이 원할하게 되지 않는 다. 아마 다른 문제도 발생 할 것으로 보인다.

실행은 아래와 같다.

1. [시작] → [실행] → gpedit.msc 입력하고 엔터칩니다. 로컬 그룹 정책 편집기가 실행됩니다.
2. [컴퓨터 구성] - [Windows 설정] - [보안 설정] - [응용 프로그램 제어 정책] - [AppLocker]에서 설정하시면 됩니다.

 

최종 적용 설정 캡쳐

20160526154613

 

 

 

 

참조 : AppLocker 규칙 동작 이해

2016년 5월 26일 목요일

윈도우 방화벽 해외 IP 차단.

윈도우 방화벽을 이용해서 한국에서의 접속 IP 만 접근 가능 하도록 파워쉘로 만들었다.


특정 포트를 지정해 줘야 한다. 기존에 allow되어 있던 부분은 사용안함 처리 해야 한다.


 


소스는 아래와 같다.


#get-help about_signing 참조하라는 에러 발생시,
#Set-ExecutionPolicy RemoteSigned  실행.


#############Config#################
$countryCode="KR" #차단을 하지 않을 나라의 CountryCode
$geoIPcsvPath="c:\GeoIPCountryWhoisPaid.csv"
#$geoIPcsvPath="\GeoIPCountryWhois.csv" #ISE에서 실행시 찾지 못함.
$ruleName="allowCountry"
$allowPort="3389,1433"
#############Config#################


$geoData=Import-Csv $geoIPcsvPath -header sIP, eIP, cc |  where-object {$_.cc –eq $countryCode} 
$geoDataTotal=$geoData.Count
$remoteIP=""


######  룰이 있는 지 체크 ########
function ruleExistsChk ($ruleName)
{
    $fw=New-object -comObject HNetCfg.FwPolicy2; # http://blogs.technet.com/b/jamesone/archive/2009/02/18/how-to-manage-the-windows-firewall-settings-with-powershell.aspx 
    $RuleCHK=$fw.rules | where-object {$_.name –eq $ruleName}
    if(!$RuleCHK){
    #$deny_rule_name + " 룰이 생성되어 있지 않습니다."; exit; 
    #허용하는 룰 생성.
    netsh advfirewall firewall add rule name="$ruleName" localport="$allowPort" protocol=TCP localip=any dir=in action=allow profile="any" interfacetype="any"
    }
}
######  룰이 있는 지 체크 ########


$count=1
foreach ($geoIP in $geoData)
{
    #$remoteIP+=@($geoIP.sIP+"-"+$geoIP.eIP+",") #배열로 저장.
     $remoteIP+=$geoIP.sIP+"-"+$geoIP.eIP+","
     try {

        
         #remoteAddr가 한개의 룰에 약 300개 이상이면 등록이 안됨. 안전하게 200으로 설정.
        if(($count%200) -eq 0)
        {
            $makeRuleName=$ruleName+$countryCode+$count
            ruleExistsChk($makeRuleName)
            netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP"
            $remoteIP=""
        }elseif($geoDataTotal -eq $count){
            $makeRuleName=$ruleName+$countryCode+$count
            ruleExistsChk($makeRuleName)
            netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP"
            $remoteIP=""
        }

    }catch {
      Write-Warning "Error occured: $_"
    }
     $count++

}


GeoIPCountryWhois.csv을 이용한 나라별 윈도우 방화벽 차단 등록.

나라별방화벽차단등록

www.2cpu.co.kr 에서 제작된 중국쪽 ip대역 차단 스크립트를 보게되었다.

실제로 GeoIPCountryWhois.csv 파일에 있는 걸 스크립트로 만든 거라서

GeoIPCountryWhois 파일이 업데이트 되면 다시 수정 해야 하는 번거로움이 있어서

파워쉘 스크립트로 만들었다.

처음에는 vb 로 만들려고 했으나, vb 자체의 자료도 별로 없고, 기존 프로그래밍 언어와 다른 점이 너무 많아서 powershell 로 바꿨다.

요즈음의 왠만한 윈도우 서버는 powershell 을 지원하니 왠만해서는 될 듯하다. 테스트는 안 해봤다.

최신의 GeoIPCountryWhois.csv 파일은 여기서 다운 받을 수 있다.

근데 파일 자체가 최신이 아니다. 2년전 자료이다.

진짜 최신자료는 www.maxmind.com 에서 유료로 받을 수 있다.



소스
#문의는 http://blog.netchk.net/
#############Config#################
$countryCode="CN" #차단할 나라의 CountryCode
#$geoIPcvsPath="c:\GeoIPCountryWhois.csv"
$geoIPcvsPath="\GeoIPCountryWhois.csv"
$ruleName="blockCountry"
#############Config#################


$geoData=Import-Csv $geoIPcvsPath -header sIP, eIP, start, end, cc, cn |  where-object {$_.cc –eq $countryCode} 
$geoDataTotal=$geoData.Count
$remoteIP=""


######  룰이 있는 지 체크 ########
function ruleExistsChk ($ruleName)
{
    $fw=New-object -comObject HNetCfg.FwPolicy2; # http://blogs.technet.com/b/jamesone/archive/2009/02/18/how-to-manage-the-windows-firewall-settings-with-powershell.aspx 
    $RuleCHK=$fw.rules | where-object {$_.name –eq $ruleName}
    if(!$RuleCHK){
    #$deny_rule_name + " 룰이 생성되어 있지 않습니다."; exit; 
    netsh advfirewall firewall add rule name="$ruleName" localip=any dir=in action=block profile="any" interfacetype="any"
    }
}
######  룰이 있는 지 체크 ########


$count=1
foreach ($geoIP in $geoData)
{
    #$remoteIP+=@($geoIP.sIP+"-"+$geoIP.eIP+",") #배열로 저장.
     $remoteIP+=$geoIP.sIP+"-"+$geoIP.eIP+","
     
     #remoteAddr가 한개의 룰에 약 300개 이상이면 등록이 안됨. 안전하게 200으로 설정.
    if(($count%200) -eq 0)
    {
        $makeRuleName=$ruleName+$countryCode+$count
        ruleExistsChk($makeRuleName)
        netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP"
        $remoteIP=""
    }elseif($geoDataTotal -eq $count){
        $makeRuleName=$ruleName+$countryCode+$count
        ruleExistsChk($makeRuleName)
        netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP"
        $remoteIP=""
    }

     $count++

}

예전 차단하는 스크립트에서도 썼지만 remoteAddress 에 limit 이 걸려 있다.

단일 IP는 약 1000개 인데, IP range는 약 300개 정도이다.

그래서 200개 단위로 rule을 다시 생성한다.



ps. 위의 소스를 이용해서 한국만 허용하고 해외는 모두 차단 하는 스크립트를 만들었는 데, 안된다. 리눅스의 iptable 같은 경우 순서에 따라 적용이 되기 때문에 모든 IP 차단, 한국 IP 허용 으로 하면 된다.

윈도우 방화벽은 순서에 따라 적용되지 않는다. 한국 IP 허용, 모든 IP 차단 해도 안되고, 순서를 바꿔서 등록 해도 역시 안된다.

방법은 있는데, 기존에 등록되어 있는 허용 포트 부분을 모두 지정하는 것이다. 한국 IP 만 등록해 놓은 룰을 적용한 후, local port 를 설정하고, 기존에 적용되어 있던 부분을 삭제 하면 된다.

문제는 포트별로 다른 IP 차단이 안된다는 점. 해외 IP를 전부 등록해야...;;

ps2. 방화벽 규칙에서 여러 룰에서 차단과 허용이 둘다 있으면 차단 시킨다.

https://technet.microsoft.com/ko-kr/library/cc755191(v=ws.10).aspx

2016년 5월 21일 토요일

Talend Open Studio(TOS) 암호화, 복호화.

TOS를 사용해서 DB 데이터를 contexts로 저장 하였다. contexts로 exprot 하면 해당 내용들이 파일로 저장되기 때문에, 몇몇개의 값 때문에 다시 빌드 하지 않아도 된다.

일종의 설정파일이다.

문제는 type을 password로 지정하면 암호화가 되는 데, 파일의 내용을 수정할 수가 없다.

이렇게 되면 패스워드 때문에 다시 빌드를 실행해야 되기 때문에 contexts로 만든 의미가 없어진다.

물론 String으로 바꿔서 저장하면 되지만 clear text로 저장되는 건 조금 꺼림칙하다.

db 접속을 위해서는 복호화가 가능 해야 하지 않을 까 생각했더니, 역시나 복호화가 가능하다.

TOS 소스 자체는 오픈되어 있고, github에서 볼 수 있다.

PasswordEncryptUtil.java 부분에 encryptPassword, decryptPassword가 있는데,

이 부분을 가져다 사용해서 간단한 프로그램으로 만들어 놓으면, 다시 빌드해야 하는 번거로움은 덜 수 있다.

2016년 5월 11일 수요일

qmailanalog 설치 및 사용 시 에러

qmailanalog를 설치 하려고 다운 받았다.

make 했더니 오류가 난다.
/usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section .tbss mismatches non-TLS reference in strerr.a(strerr_sys.o)
/lib/libc.so.6: could not read symbols: Bad value
collect2: ld returned 1 exit status

위와같은 오류발생시 error.h파일에 extern int errno; 이줄 삭제 #include <errno.h> 그위치에 이줄 추가한다.
출처
cat /var/log/maillog | awk '{$1="";$2="";$3="";$4="";$5="";print}' > /tmp/qmailLogTmp
cat /tmp/qmailLogTmp | /usr/local/qmailanalog/bin/matchup | /usr/local/qmailanalog/bin/zoverall > /tmp/qmailLog

위와 같이 했더니, 오류 발생.
matchup: fatal: unable to write fd 5: file descriptor not open

나눠져 있는 로그 파일을 합치라고 하면서 아래와 같이 코드를 적어 놨음.
(무려 중국 블로그)
<log.1 matchup >out.1 5>pending.2
cat pending.2 log.2 | matchup >out.2 5>pending.3
cat pending.3 log.3 | matchup >out.3 5>pending.4

왜 이렇게 하는 지 모르겠음.

그냥 이렇게 하니까 된다.
cat /var/log/maillog* | awk '{$1="";$2="";$3="";$4="";$5="";print}' > /tmp/qmailLogTmp
cat /tmp/qmailLogTmp | /usr/local/qmailanalog/bin/matchup | /usr/local/qmailanalog/bin/zoverall > /tmp/qmailLog

/tmp/qmailLog 내용을 보면

[root@mail qmailanalog-0.70]# cat /tmp/qmailLog
Basic statistics

qtime is the time spent by a message in the queue.

ddelay is the latency for a successful delivery to one recipient---the
end of successful delivery, minus the time when the message was queued.

xdelay is the latency for a delivery attempt---the time when the attempt
finished, minus the time when it started. The average concurrency is the
total xdelay for all deliveries divided by the time span; this is a good
measure of how busy the mailer is.

Completed messages: 18684
Recipients for completed messages: 24230
Total delivery attempts for completed messages: 24458
Average delivery attempts per completed message: 1.30903
Bytes in completed messages: 5.20127e+09
Bytes weighted by success: 1.00912e+10
Average message qtime (s): 15.4838

Total delivery attempts: 24458
success: 24060
failure: 170
deferral: 228
Total ddelay (s): 158313.276733
Average ddelay per success (s): 6.579937
Total xdelay (s): 169514.560113
Average xdelay per delivery attempt (s): 6.930843
Time span (days): 7.42548
Average concurrency: 0.264222

잘 나온다.

근데 내가 원하는 내용이 아니다. ㅠㅠ

2016년 5월 10일 화요일

bulk insert 시 에러.

아래와 같은 에러 메시지 발생
메시지 4866, 수준 16, 상태 8, 줄 1
대량 로드하지 못했습니다. 데이터 파일의 행 1, 열 24에서 열이 너무 깁니다. 필드 종결자와 행 종결자를 제대로 지정했는지 확인하십시오.
메시지 7301, 수준 16, 상태 2, 줄 1
연결된 서버 "(null)"의 OLE DB 공급자 "BULK"에서 필수 인터페이스("IID_IColumnsInfo")를 가져올 수 없습니다.

필드 종결자를 바꿈.
\r\n 이 아님.
\n 으로 바꾸고 잘됨.

mssql 우편번호 쉽게 넣기, 업데이트

관리하는 사이트 중에 우편번호를 DB 에 저장해서 사용하는 곳이 있다.
DB에 저장해서 사용하다 보니 주기적으로 계속 업데이트를 해 줘야 한다.
sql server management studio 프로그램의 데이터 가져오기를 이용해서 넣어 줬다.

우체국 사이트에서 제공하는 데이터가 각 도별 txt 파일이다.
우리나라의 전체 도가 17개인데, ssms 프로그램으로 넣으려면 무려 반복 노가다를 17번을 해야 한다.

bulk insert를 이용해서 한번에 insert 시키도록 하였다.
bulk insert를 하려면 양식(formatfile)이 필요하다.
cmd 창을 열고 아래와 같이 입력해서 뽑아 내자.
C:\Users\Administrator>bcp mydb.dbo.T_ZIPCODE format nul -c -x -f crmZipcode.a.xml -t"|" -T

해당 파일을 바로 사용 하면 좋은데, 우체국 제공 컬럼과 실제 컬럼이 일치 하지 않는 다. 수정이 필요하다.
관리 사이트와 우체국 우편번호 데이터 컬럼의 다른 점은 다음과 같다.
1. 20번 컬럼인 '행정동' 컬럼이 없다.
2. 25번 컬럼인 '구우편번호' 컬럼이 없다.
3. 26번 컬럼인 '우편번호일련번호' 컬럼이 1번째에 있다.

변경하면 다음과 같다.
<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<!--파일의 필드 -->
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="14" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="3" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="60" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="4" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="60" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="5" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="60" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="6" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="7" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="100" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="8" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="100" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="9" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="160" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="10" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="500" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="11" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="4" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="12" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="13" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="14" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="50" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="15" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="400" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="16" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="500" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="17" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="60" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="18" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="19" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="20" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="100" COLLATION="Korean_Wansung_CI_AS"/> <!-- 행정동 -->
<FIELD ID="21" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="100" COLLATION="Korean_Wansung_CI_AS"/> <!--산여부 -->
<FIELD ID="22" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="4" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="23" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="24" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="25" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="40" COLLATION="Korean_Wansung_CI_AS"/>
<FIELD ID="26" xsi:type="CharTerm" TERMINATOR="\n" MAX_LENGTH="12"/>
</RECORD>
<!--서버의 필드 -->
<ROW>
<COLUMN SOURCE="26" NAME="SEQ" xsi:type="SQLINT"/>
<COLUMN SOURCE="1" NAME="ZIPCODE" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="2" NAME="SIDO" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="3" NAME="ESIDO" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="4" NAME="SIGUNGU" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="5" NAME="ESIGUNGU" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="6" NAME="EUPMRN" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="7" NAME="EEUPMRN" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="8" NAME="ROADCODE" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="9" NAME="ROADNAME" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="10" NAME="EROADNAME" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="11" NAME="ZIYN" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="12" NAME="GUNBON" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="13" NAME="GUNBU" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="14" NAME="GUNSEQ" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="15" NAME="DABE" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="16" NAME="GUNNAME" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="17" NAME="BUBCODE" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="18" NAME="BUBDONG" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="19" NAME="RI" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="21" NAME="SANYN" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="22" NAME="ZIBON" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="23" NAME="EUPSEQ" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="24" NAME="ZIBU" xsi:type="SQLNVARCHAR"/>
</ROW>
</BCPFORMAT>
<!-- 서버의 필드에 없는 것은 컬럼을 넣지 않음. -->
<!-- 파일의 필드는 쓰던 쓰지 않던 모두 넣음 -->
<!-- 베이스가 되는 파일 생성 명령어 : C:\Users\Administrator>bcp mydb.dbo.T_ZIPCODE format nul -c -x -f crmZipcode.a.xml -t"|" -T -->

이 양식을 이해 하는 데, 조금 오래 걸렸다.
간단히 설명하면,
1. 상단 RECORD 는 파일의 컬럼이다. 전부 있어야 된다.
2. 하단 ROW는 테이블의 컬럼이다. 수정해서 써야 한다.
내껄 보면 26번이 처음 있고, 20번과 25번이 없는 걸 알 수 있다.
bulk insert 쿼리는 다음과 같다.
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\강원도.txt'            WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\경기도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\경상남도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\경상북도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\광주광역시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\대구광역시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\대전광역시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\부산광역시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\서울특별시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\세종특별자치시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\울산광역시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\인천광역시.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\전라남도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\전라북도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\제주특별자치도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\충청남도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )
BULK INSERT mydb.[dbo].[T_ZIPCODE] FROM 'C:\Users\Administrator\Downloads\zipcode_DB\지역별전체 DB\20160504_우편번호_지역별주소\충청북도.txt' WITH ( FIRSTROW = 2, formatfile='C:\Users\Administrator\crmZipcod.xml' )


FROM 절과 formatfile 의 위치를 수정해서 사용하면 된다.
path를 변수로 만들고 싶었으나, 기본적으로 지원하지 않고, 동적 sql을 사용해야 한다길래 그냥 뒀다.

 

대략 30분가량의 노가다를 없앴다.  :)