[POWERSHELL] 파워쉘을 이용한 파일 정보 확인하기(Write a get file information script)

파워쉘에 대한 이야기를 잠깐 할까합니다. 윈도우 환경에서 파워쉘 사용 시 batch 파일에 비해 상세하게 시스템에 대해 제어할 수 있고 Ruby, Python 과 같은 언어와 달리 기본적으로 내장되어 있기 때문에 별도의 설치 없이 사용할 수 있는 장점이 있습니다.

오늘은 파워쉘을 이용해서 파일에 대한 정보를 가져오고, 내용을 보는 방법에 대해 정리하고 이를 통해 간단하게 파일 정보에 대해 확인하는 스크립트를 만들어보도록 하죠.

Get File information

get-itemproperty 를 사용하면 쉽게 파일에 대한 정보를 가져올 수 있습니다. .py 파일에 대해 가져와보면..

기본적인 정보부터, 생성,수정일 등등 여러가지 정보를 획득할 수 있습니다.

PS C:>get-itemproperty -Path app.py Format-list -Property * -Force

PSPath : Microsoft.PowerShell.Core\FileSystem::C:\Users\Administrator\Desktop\app.py PSParentPath : Microsoft.PowerShell.Core\FileSystem::C:\Users\Administrator\Desktop PSChildName : app.py PSDrive : C PSProvider : Microsoft.PowerShell.Core\FileSystem VersionInfo : File: C:\Users\Administrator\Desktop\app.py InternalName: OriginalFilename: FileVersion: FileDescription: Product: ProductVersion: Debug: False Patched: False PreRelease: False PrivateBuild: False SpecialBuild: False Language:

BaseName : app Mode : -a— Name : app.py Length : 831 DirectoryName : C:\Users\Administrator\Desktop Directory : C:\Users\Administrator\Desktop IsReadOnly : False Exists : True FullName : C:\Users\Administrator\Desktop\app.py Extension : .py CreationTime : 2017-05-15 오후 12:01:18 CreationTimeUtc : 2017-05-15 오전 3:01:18 LastAccessTime : 2017-05-15 오후 12:01:16 LastAccessTimeUtc : 2017-05-15 오전 3:01:16 LastWriteTime : 2017-05-15 오후 1:37:44 LastWriteTimeUtc : 2017-05-15 오전 4:37:44 Attributes : Archive

뒤에 Format-list -Property * -Force 부분은 데이터를 조금 더 좋게 표현하기 위해 파이프로 넘겨 출력 형태를 변경한 것입니다. 파워쉘은 각각 출력 데이터가 Object 처럼 지정되어 있기 때문에 출력 형태를 변형하거나 필요한 데이터를 읽기 매우 쉽습니다.

Get Binary information

get-content를 이용하면 파일 내용을 읽을 수 있습니다.

PS C:>get-content “File”

형태로 넘겨주면 파일에 따라 알수없는 값이 나타나기도 합니다. 당연히.. txt 같이 plan text가 들어있다면 잘 보이겠지만 실행 파일처럼 바이너리들은 깨진 문자를 만나게 되죠. 그래서 우린 -Encoding 인자를 넘겨주어 표현할 인코딩을 지정해줍니다. UTF8, Byte 등이 많이 쓰이죠.

get-content “Path” -Encoding UTF8 Select-Object -First 50
get-content “Path” -Encoding Byte Select-Object -First 50
get-content “Path” Select-Object -First 50

get-content 이외에도 OpenRead()를 통해 파일 데이터를 읽어올 수 있습니다. 편의에 따라 사용하시면 좋을 것 같네요. 아래는 파일을 읽어 Byte로 출력해주는 스크립트 코드입니다. [System.IO.File]::OpenRead()로 대상 파일을 읽은 후 내부 데이터를 Byte 형태로 출력해줍니다.

$bufferSize = 65536
$stream = [System.IO.File]::OpenRead("File Path")
while ( $stream.Position -lt $stream.Length ) {
#BEGIN CALLOUT A
  $buffer = new-object Byte[] $bufferSize
  $bytesRead = $stream.Read($buffer, 0, $bufferSize)
#END CALLOUT A
  for ( $line = 0; $line -lt [Math]::Floor($bytesRead /
  16); $line++ ) {
    $slice = $buffer[($line * 16)..(($line * 16) + 15)]
    (("{0:X2} {1:X2} {2:X2} {3:X2} {4:X2} {5:X2} ") +
    ("{6:X2} {7:X2} {8:X2} {9:X2} {10:X2} {11:X2} ") +
    ("{12:X2} {13:X2} {14:X2} {15:X2} ")) -f $slice
  }
#BEGIN CALLOUT B
  if ( $bytesRead % 16 -ne 0 ) {
    $slice = $buffer[($line * 16)..($bytesRead - 1)]
    $output = ""
    foreach ( $byte in $slice ) {
      $output += "{0:X2} " -f $byte
    }
    $output
#END CALLOUT B
  }
}
$stream.Close()

Get file information script

위 2가지를 조합해보면 파일에 대한 정보를 불러오는 스크립트를 만들 수 있습니다. 사실 다른 수집 코드도 내용만 붙여가면 더 좋은 스크립트가 될거라 생각합니다.

finfo.ps1

Param (
[Parameter(Mandatory=$true)] // 파일 이름을 꼭 받도록 Mandatory 지정
$path
)

Write-Host " ---- < File Default Information > "
get-itemproperty -Path $path | Format-list -Property * -Force
Write-Host " ---- < Binary Hex Data > "
$bufferSize = 65536
$stream = [System.IO.File]::OpenRead($path)
while ( $stream.Position -lt $stream.Length ) {
#BEGIN CALLOUT A
  $buffer = new-object Byte[] $bufferSize
  $bytesRead = $stream.Read($buffer, 0, $bufferSize)
#END CALLOUT A
  for ( $line = 0; $line -lt [Math]::Floor($bytesRead /
  16); $line++ ) {
    $slice = $buffer[($line * 16)..(($line * 16) + 15)]
    (("{0:X2} {1:X2} {2:X2} {3:X2} {4:X2} {5:X2} ") +
    ("{6:X2} {7:X2} {8:X2} {9:X2} {10:X2} {11:X2} ") +
    ("{12:X2} {13:X2} {14:X2} {15:X2} ")) -f $slice
  }
#BEGIN CALLOUT B
  if ( $bytesRead % 16 -ne 0 ) {
    $slice = $buffer[($line * 16)..($bytesRead - 1)]
    $output = ""
    foreach ( $byte in $slice ) {
      $output += "{0:X2} " -f $byte
    }
    $output
#END CALLOUT B
  }
}
$stream.Close()

실행해보면..

PS C:> .\finfo.ps1 .\app.py —- < File Default Information >

PSPath : Microsoft.PowerShell.Core\FileSystem::C:\Users\Administrator\Desktop\app.py PSParentPath : Microsoft.PowerShell.Core\FileSystem::C:\Users\Administrator\Desktop PSChildName : app.py PSDrive : C PSProvider : Microsoft.PowerShell.Core\FileSystem VersionInfo : File: C:\Users\Administrator\Desktop\app.py InternalName: OriginalFilename: FileVersion: FileDescription: Product: ProductVersion: Debug: False Patched: False PreRelease: False PrivateBuild: False SpecialBuild: False Language:

BaseName : app Mode : -a— Name : app.py Length : 831 DirectoryName : C:\Users\Administrator\Desktop Directory : C:\Users\Administrator\Desktop IsReadOnly : False Exists : True FullName : C:\Users\Administrator\Desktop\app.py Extension : .py CreationTime : 2017-05-15 오후 12:01:18 CreationTimeUtc : 2017-05-15 오전 3:01:18 LastAccessTime : 2017-05-15 오후 12:01:16 LastAccessTimeUtc : 2017-05-15 오전 3:01:16 LastWriteTime : 2017-05-15 오후 1:37:44 LastWriteTimeUtc : 2017-05-15 오전 4:37:44 Attributes : Archive

—- < Binary Hex Data > 69 6D 70 6F 72 74 20 74 68 72 65 61 64 69 6E 67 0A 69 6D 70 6F 72 74 20 73 75 62 70 72 6F 63 65 73 73 0A 69 6D 70 6F 72 74 20 6F 73 0A 69 6D 70 6F 72 74 20 73 79 73 0A 69 6D 70 6F 72 74 20 67 6C 6F 62 0A 0A 64 65 66 20 72 75 6E 54 68 72 65 61 64 28 71 75 65 72 79 29 3A 0A 09 66 6F 72 20 69 20 69 6E 20 72 61 6E 67 65 28 61 70 70 4C 69 73 74 43 6F 75 6E 74 29 3A 0A 09 09 70 72 69 6E 74 20 71 75 65 72 79 2B 61 70 70 4C 69 73 74 5B 69 5D 0A 09 09 23 6F 73 2E 73 79 73 74 65 6D 28 71 75 65 72 79 29 0A 09 0A 74 68 72 65 61 64 73 20 3D 20 5B 5D 0A 63 62 65 20 3D 20 22 61 64 62 20 2D 73 20 22 0A 63 61 66 20 3D 20 22 20 69 6E 73 74 61 6C 6C 20 22 0A 71 75 65 72 79 20 3D 5B 5D 0A 23 61 70 70 6E 61 6D 65 20 3D 20 73 79 73 2E 61 72 67 76 5B 31 5D 0A 0A 61 70 70 4C 69 73 74 20 3D 20 67 6C 6F 62 2E 67 6C 6F 62 28 22 2E …..

여기에 파워쉘 Refernce를 참조하며 필요한 데이터 수집 부분을 더한다면 윈도우에서 사용할 수 있는 아주 편리한 파일 분석 스크립트로 만들수도 있을 것 같습니다.

상세한 Function 에 대한 정보는 MSDN 찾아보시면 잘 나옵니다. https://msdn.microsoft.com/en-us/library/ms714469(v=vs.85).aspx

Reference

http://windowsitpro.com/powershell/get-hex-dumps-files-powershell https://msdn.microsoft.com/en-us/library/ms714469(v=vs.85).aspx