Reminiscence


PowerShell
이용하면서 PowerShell 내에서 FTP 데이터를 다운 받아 처리 있는 방법은 없을까 고민하던 FTP 관련 함수들을 찾아보기 시작했습니다.

 

PowerShell에서 FTP 대한 기능들을 사용 있도록 해주는 모듈을 판매하는 업체도 있었지만, 해당 모듈을 구매하여 사용하는 것은 의미가 없으므로, 실제 데이터를 주고 받을 있는 함수들을 찾아보았습니다.

 

아래 내용은 FTP 이용하여 파일을 다운로드 하는 스크립트 입니다.

아래 내용에서 가장 중요한 부분은 .NET Component 사용하는 부분이며, 이에 대한 자세한 정보는 http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx 에서 확인 있습니다.

 

 

# Get-FTPfile 함수를 선언

function Get-FTPFile ($Source,$Target,$UserName,$Password) 

{ 

 

# FTP 주소를 .Net 컴포넌트중 FtpWebRequest의 Craete명령을 통해 열어 줍니다.

# 단, 이때 사용되는 $Source 주소의 경우 FTP Web Request이기 때문에 FTP://주소/ 형식으로 입력되어야 합니다.

$ftprequest = [System.Net.FtpWebRequest]::create($Source) 

 

 

# NetworkCredential Class는 기본, 다이제스트, NTLM, Kerberos 인증과 같은 암호 기반의 인증 체계에 자격증명을 제공하기 위해서 사용 합니다.

# 참고 : http://msdn.microsoft.com/ko-kr/library/system.net.networkcredential(v=VS.80).aspx

 

$ftprequest.Credentials = 

    New-Object System.Net.NetworkCredential($username,$password) 

 

# ::DownloadFile : FTP 서버에서 파일을 다운로드 하는데 사용되는 FTP RETR 프로토콜 메서드를 나타냅니다.

$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile 

# UseBinary : FTP 서버에서 파일 전송시 데이터 형식을 지정하는 Boolean 값을 설정 합니다.

$ftprequest.UseBinary = $true 

# KeepAlive : FTP 서버에서 제어 연결이 요청 완료 후 닫히는지 여부를 결정 합니다. 지속적인 세션 유지를 위해 False 값을 줍니다.

$ftprequest.KeepAlive = $false 

 

# FTP 서버에 응답을 반환 하는 메서드를 ftpresponse에 지정합니다.

$ftpresponse = $ftprequest.GetResponse() 

 

# FTP 서버에서 보낸 응답 데이터를 포함하는 스트림을 검색하여 reponsestream에 지정합니다.

$responsestream = $ftpresponse.GetResponseStream() 

 

# System.IO.FileStream 클래스를 사용하여 로컬 시스템의 디렉토리에 파일을 생성 할 수 있도록 준비 합니다.

# 이때 아래 [IO.FileMode]::Create는 로컬 시스템에서 파일을 생성할때 동일한 이름이 있으면 덮어쓰고, 동일한 이름이 없으면 새로 생성 함을 의미 합니다.)

$targetfile = New-Object IO.FileStream ($Target, [IO.FileMode]::Create) 

 

# 파일을 받을 때 버퍼로 사용 할 ByteArray 변수를 생성합니다.

[byte[]]$readbuffer = New-Object byte[] 1024 

 

# ResponseStream.Read 메서드를 이용하여 Response된 Stream의 데이터를 Readbuffer에 저장하고 1024Byte 만큼 저장되면 이를 IO.FileStream의 Write 메서드를 이요하여 파일로 작성 합니다.

# 이 과정은 ResponseStream에서 읽어들인 데이터가 0일때까지 계속 됩니다. (파일을 받아오는 과정)

# 이와 관련된 과정은 http://msdn.microsoft.com/ko-kr/library/yet8z89t.aspx  http://msdn.microsoft.com/ko-kr/library/system.io.stream.read.aspx 를 참조하시기 바랍니다.

do{ 

    $readlength = $responsestream.Read($readbuffer,0,1024) 

    $targetfile.Write($readbuffer,0,$readlength) 

} 

while ($readlength -ne 0) 

# IO.FileStream.Close 메서드를 이용하여 파일을 닫습니다.

$targetfile.close() 

} 

 

# Get-FTPFile 함수 호출을 위한 기본적인 정보들을 입력합니다. 

$sourceuri = "ftp://MyFtpServer/FolderPath\File.txt" 

$targetpath = "C:\temp\MyFile.txt" 

$user = "Username" 

$pass = "Password" 

Get-FTPFile $sourceuri $targetpath $user $pass

 


다음편에서는
FTP 이용하기 (Upload Delete)편을 준비하도록 하겠습니다.

 

감사합니다.


저작자 표시 비영리
신고

댓글 0개가 달렸습니다.


PowerShell을 이용하여 IIS 로그파일 경로를 지정하시면 송/수신된 데이터 량을 확인 할 수 있습니다.
여기서 약간 더 변형을 한다면, IIS의 내용중 로그 디렉토리에 대한 정보를 확인하여 각 사용자 별로 일일 송/수신 데이터 량을 확인 할 수도 있습니다.

우선 소스부터 보시죠..

# 로그 파일 경로를 입력 받습니다.
Param (
  [String] $Path
)
# 필요한 변수들을 미리 지정 합니다.
[INT]$RECV_TOTAL="0"
[INT]$SEND_TOTAL="0"
[INT]$CS_NUM=0;
[INT]$SC_NUM=0;
 
$KB=1024
$MB=1024*1024
$GB=1024*1024*1024
get-content $Path | %{
    #Pattern Check
    if ( $_ | Select-String -Pattern "#Fields" ) {
        # Fields 값에 대한 마이너스 값 처리.
        [INT]$CNT=-1;
        foreach ($element in $_.Split(' '))
        {
           if ( $element -eq "sc-bytes" ){
             $SC_NUM=$CNT;
           }elseif ( $element -eq "cs-bytes" ) {
             $CS_NUM=$CNT;
           }
           $CNT+=1;
        }
     }
     elseif ( $_ | Select-String -Pattern "^[^#]" )
     {
# 실제 송/수신된 값을 Split 명령을 통해 저장합니다.
 [int]$SEND_BYTE=$_.Split(' ')[$SC_NUM];
 [int]$RECV_BYTE=$_.Split(' ')[$CS_NUM];
 [int]$RECV_TOTAL+=$RECV_BYTE;
 [int]$SEND_TOTAL+=$SEND_BYTE;
    }
}
If ( $RECV_TOTAL -gt $GB ){
 $RECV_TOTAL = $RECV_TOTAL / $GB
 Write-Host "Total  In : $RECV_TOTAL GByte"
} elseif ( $RECV_TOTAL -gt $MB){
        $RECV_TOTAL = $RECV_TOTAL / $MB
 Write-Host "Total  In : $RECV_TOTAL MByte"
}elseif ( $RECV_TOTAL -gt  $KB){
 $RECV_TOTAL = $RECV_TOTAL / $KB
 Write-Host "Total  In : $RECV_TOTAL KByte"
}else{
 Write-Host "Total  In : $RECV_TOTAL Byte"
}
If ( $SEND_TOTAL -gt $GB ){
 $SEND_TOTAL = $SEND_TOTAL / $GB
 Write-Host "Total Out : $SEND_TOTAL GByte"
} elseif ( $SEND_TOTAL -gt $MB){
        $SEND_TOTAL = $SEND_TOTAL / $MB
 Write-Host "Total Out : $SEND_TOTAL MByte"
}elseif ( $SEND_TOTAL -gt  $KB){
 $SEND_TOTAL = $SEND_TOTAL / $KB
 Write-Host "Total Out : $SEND_TOTAL KByte"
}else{
 Write-Host "Total Out : $SEND_TOTAL Byte"
}

우선 간단한 소스이니 얼마든지 변형이 가능 합니다.
추가적으로 더 나간다면, 여러대의 서버를 관리하는 관리자의 경우 각 서버들에 대한 FTP 접속 계정을 만들고 FTP로 접속하여 각 로그 파일들을 다운로드 받은 뒤 해당 파일에 대한 체크 후 자동 삭제 하는 과정을 통해 모든 IIS 서버에 대한 각 계정별 트래픽 값을 확인 할 수도 있습니다.

그냥 단순히 참고만.. ^^.
저작자 표시 비영리
신고

댓글 0개가 달렸습니다.


1. PowerShell의 인증

PowerShell
사용하면서 외부의 스크립트를 실행하거나, 로컬에서 스크립트를 실행해야 하는 경우가 발생하게 되는데, 이때 대부분 실행정책(Execution_Policy) 인하여 정상적인 실행이 되지 않는 경우가 발생 합니다.

 

문제를 해결하기 위해서는 Execution Policy RemoteSigned 수정하거나, 인증서를 생성하여 인증 절차를 진행해야 하는데, RemoteSigned 대한 내용은 너무 쉽고 간단하므로, 인증서를 발급받아 처리 하는 과정에 대하여 보도록 하겠습니다.

- RemoteSigned 설정 방법 보기 ▼ more Click!

더보기


우선
인증서를 생성하기 위해서는 인증 과정을 알아야 입니다.

PowerShell 이러한 인증 과정에 대하여 상세하게 매뉴얼로 설명을 하고 있으며, 매뉴얼을 PowerShell 내에서도 확인 수가 있습니다.


- About_Signing
관련 문서 : http://technet.microsoft.com/ko-kr/library/dd347649.aspx

- About_Signing 매뉴얼 명령어 : [Get-Help about_signing]

 

Microsoft에서 제공하는 뉴얼을 보면 스크립트 서명 방법에 대하여 2가지를 제시하고 있습니다.

  • 공인 인증 기관에서 만든 인증서 : 공인 인증기관에서 유료로 사용자에게 발급하는 코드 서명 인증서
  • 사용자가 만든 인증서 :사용자가 자신의 컴퓨터를 인증기관 역할을 있도록 설정하여 자체 서명된 인증서를 발급하므로 무료로 발급하여 사용이 가능.


PowerShell
공부하는데 돈이 들어가면 안되겠죠? 우리는 여기서 사용자가 만든 인증서(개인 인증서)를 이용하도록 하겠습니다.


2. PowerShell의 개인 인증서 만들기
 

인증서를 만들기 위해서는 우선 인증서 생성 도구가 있어야 하며, 도구는 .Net Framework SDK 1.1 이상 버전에 포함되어 있으며 아래 URL에서 다운로드 받을 있습니다.

  • .NET Framework SDK 2.0 Download : http://www.microsoft.com/downloads/details.aspx?familyid=fe6f2099-b7b4-4f47-a244-c96d69c35dec&displaylang=en
  • Window SDK Download : http://msdn.microsoft.com/ko-kr/windows/bb980924.aspx
  • MakeCert 관련 문서 : http://go.microsoft.com/fwlink/?LinkId=119097
  •  

     

    저는 제가 사용중인 Windows7 맞는 SDK Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1 다운로드 받아 설치하였습니다.

     

    모든 설치가 완료 되었다면, 이제 인증서 생성 도구인 makecert 실행해야 하지만, 그전에 사전 준비 작업을 진행하도록 하겠습니다.

    1) 우선 시
    버튼을 누른 mmc.exe 실행 하도록 합니다.


    2) 콘솔 창이 열리면 [파일] -> [스냅인 추가/제거] 버튼을 눌러 스냅인 페이지를 띄워줍니다. (단축키는 Ctrl + M)
    3)
    [스냅인 추가/제거] 창이 열리면 [인증서] 선택 추가 버튼을 누릅니다.


    4) 스냅인이 관리할 인증서 대상은 [ 사용자 계정] 선택 마침을 눌러 스냅인을 완료 합니다.
     

    스냅인이 완료 되었다면, 이제 실제 개인 인증서를 생성해야 합니다. 이를 생성하기 위해서는 위에서 말씀 드린바와 같이 makecert 툴을 사용해야 합니다.


    Windows SDK
    설치한 경우라면, Windows 7 SDK 포함된 CMD 띄워서 실행하도록 하겠습니다.


     

    위와 같이 makecert 실행되는 것을 확인 했다면, 다음 명령어를 실행하여 인증서를 생성하도록 합니다.
     

    <Root 인증서>

    makecert -n "CN=PowerShell Local Certificate Root" -a sha1 -eku 1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer -ss Root -sr LocalMachine


    Root
    인증서를 생성하기 위해 위와 같이 명령어를 실행했다면, 아래 그림과 같이 개인키 암호 만들기 라는 창이 보여질 입니다.

     

    보안상 암호를 설정 하도록 하겠습니다.

    2번의 암호 설정 입력이 끝나면, 입력한 암호에 대하여 확인하는 암호 입력창이 다시 한번 출력됩니다.



     정상적으로 Root 인증서와 사용자 인증서가 설치되었다면, MMC에서 해당 내용을 확인 있습니다.

    [MMC 실행 인증서 스냅인 추가] -> [신뢰할 있는 루트 인증기관] -> [인증서] -> [PowerShell Local Certificate Root]


     

    관리자 인증서 생성이 완료되었으니, 이제 사용자 인증서를 생성해 보도록 하겠습니다.


    <사용자 인증서>
     

    makecert -pe -n "CN=PowerShell User" -ss MY -a sha1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk -ic root.cer


    Root 인증서를 만들때와 마찬가지로 개인키 암호를 입력하는 창이 출력되며, 해당 창에 개인키에 대한 암호를 입력하시면 정상적으로 생성이 됩니다.


     

    이제 Root 인증서와 사용자 인증서 2 모두 생성이 되었으니, 사용자 인증서에 대한 내용을 PowerShell에서 확인해 보도록 하겠습니다.

     

    PowerShell 창에서 아래 명령어 입력을 통해 확인이 가능 합니다.

    PS C:\Windows\system32> Get-Childitem cert:\CurrentUser\my -codesigning

     

        디렉터리: Microsoft.PowerShell.Security\Certificate::CurrentUser\my

     

    Thumbprint                                                  Subject

    ----------                                                      -------

    A9BB73523B24247BCFBE9B7B7E0B7723F559209C  CN=PowerShell User


    생성된 인증서는 MMC 스냅인을 통해서도 확인이 가능 합니다.

     

    정상적으로 인증서를 만들었다면, 인증서를 이용해서 자신이 실행하고자 하는 스크립트 또는 작성한 스크립트에 Signing 진행해 보도록 하겠습니다.

    아래 내용은 Sign 되지 않은 스크립트와 Sign 스크립트의 실행 결과 차이 입니다.

     

    PS C:\Users\mrmsm.SDS> Set-ExecutionPolicy Allsigned

    PS C:\Users\mrmsm.SDS> .\GetProcess_Script.ps1

    C:\Users\mrmsm.SDS\GetProcess_Script.ps1 파일을 로드할 수 없습니다. C:\Users\mrmsm.SDS\GetProcess_Script.ps1 파일에 디

    지털 서명하지 않았습니다. 스크립트가 시스템에서 실행되지 않습니다. 자세한 내용은 "get-help about_signing"을 참조하십시오..

    위치 줄:1 문자:24

    + .\GetProcess_Script.ps1 <<<<

        + CategoryInfo          : NotSpecified: (:) [], PSSecurityException

        + FullyQualifiedErrorId : RuntimeException

     

    PS C:\Users\mrmsm.SDS> $cert = @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]

    PS C:\Users\mrmsm.SDS> Set-AuthenticodeSignature .\GetProcess_Script.ps1 $cert

     

        디렉터리: C:\Users\mrmsm.SDS

     

    SignerCertificate                                             Status                                 Path

    -----------------                                               ------                                 ----

    79DBB89D221B3B7A4266E39D8F79F049CE03A644  Valid                                  GetProcess_Script.ps1

     

    PS C:\Users\mrmsm.SDS> .\GetProcess_Script.ps1

     

    Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName

    -------  ------    -----      ----- -----   ------     -- -----------

        420      10     6140       8696    88     9.80   3532 atbsvc

        535       5     1304       1868    49            1356 atieclxx

         97       4      820       1240    27             940 atiesrxx

        118       5    15352      14208    40            5108 audiodg

         74       4     1672       1388    55            4032 CKAgent

         75       7    11044        532    84     0.08   5864 ClientSM

         95       5     4956       9364    64     1.97   6272 conhost

     

                            --- 생략 ---



    위의 내용을 보면 ExecutionPolicy Allsigned 설정함으로써 Sign 스크립트만 실행하도록 설정하였고, Sign되지 않은 스크립트는 로드 되지 않고 에러메세지가 출력됨을 확인 있습니다. 스크립트에 Set-AuthenticodeSignature 명령을 이용하여 Sign 진행 하였고, 실행 결과가 정상적으로 출력됨을 확인 있습니다.

     

    Set-AuthenticodeSignature 명령에 대한 자세한 사용 방법은 [Get-Help Set-AuthenticodeSignature] 명령을 입력하여 확인이 가능 합니다.



    !! 알고 가세요

     PowerShell ISE에서 작성한 스크립트를 Signature 경우 아래 내용과 같이 정상적인 Signing 되지 않는 현상이 발생 있습니다. 이는 PowerShell ISE 버그로 ISE에서 생성된 스크립트는 Signing 되지 않음을 아래 URL에서 확인하실 있습니다.

    # notepad에서 작성한 Script

    PS C:\Users\mrmsm.SDS> Set-AuthenticodeSignature .\GetProcess_Script.ps1 $cert

     

        디렉터리: C:\Users\mrmsm.SDS

     

    SignerCertificate                                         Status                                 Path

    -----------------                                            ------                                  ----

    79DBB89D221B3B7A4266E39D8F79F049CE03A644  Valid                                  GetProcess_Script.ps1

     

    # PowerShell ISE에서 작성한 Scirpt

    PS C:\Users\mrmsm.SDS> Set-AuthenticodeSignature .\ISE_Script.ps1 $cert

     

        디렉터리: C:\Users\mrmsm.SDS

     

    SignerCertificate                      Status                                     Path

    -----------------                         ------                                       ----

                                              UnknownError                           ISE_Script.ps1

    - ISE 버그 관련 참고 URL : http://connect.microsoft.com/PowerShell/feedback/details/483431/set-authenticodesignature-fails-on-scripts-created-from-iSe


    !! 알고 가세요
     Set-ExecutionPolicy 사용하는데에 있어 실행 정책들이 어떤 내용을 가지고 있는지 모르고 설정 하면 안되겠죠?
    다음 내용은 ExecutionPolicy 대한 변수들의 설명입니다.

    • Restricted : 구성 파일을 로드하거나 스크립트를 실행하지 않습니다. 기본값 입니다.
    • AllSigned : 로컬 컴퓨터에 ㅈ가성하는 스크립트를 포함하여 모든 스크립트 구성파일에 신뢰된 게시자가 서명해야 합니다.
    • RemoteSigned : 인터넷에서 다운로드한 모든 스크립트 구성파일에 대해 신뢰된 게시자가 서명해야 합니다. (, 로컬에서 작성한 스크립트는 문제가 없습니다.)
    • Unrestricted : 모든 구성파일을 로드하고 모든 스크립트를 실행합니다. 인터넷에서 다운로드한 서명되지 않은 스크립트를 실행할 경우 실행하기 전에 사용권한을 묻는 메시지가 표시됩니다.
    • ByPass : 아무것도 차단하지 않으며, 경고나 메시지도 표시되지 않습니다.
    • Underfinded : 현재 할당된 실행 정책을 현재 범위에서 제거 합니다. 매개변수는 그룹정책 범위에 설정된 실행 정책을 제거하지 않습니다.

    우리가 흔히 Local 상에서 작성한 스크립트가 실행되지 않을 [Set-ExecutionPolicy RemoteSigned] 실행하라고 합니다. 명령을 실행하면 인터넷에서 다운로드한 모든 스크립트에 대해서만 Signature 필요하기 때문에 Local에서 작성한 스크립트는 아무런 제약 없이 실행 수가 있는 것입니다.

    <참고 URL>
    http://technet.microsoft.com/ko-kr/library/dd347649.aspx
    http://www.hanselman.com/blog/SigningPowerShellScripts.aspx
    http://technet.microsoft.com/ko-kr/library/dd347628.aspx

    저작자 표시 비영리
    신고

    댓글 0개가 달렸습니다.