Powershell을 활용해 시스템 정보 수집하기
powershell 에 대한 기본적인 내용들을 다뤄보고자 한다.
1. powershell 변수
powershell에서는 shell script와 같이 변수를 선언하거나 활용할 때 $를 사용한다.
# psversion 정보를 psversion 변수에 저장
$psversion = $PSVersionTable.psversion.tostring()
powershell에는 상태 정보를 저장하는 자동 생성 변수들이 있다.
1-1. 환경 정보 관련 변수
변수 | 설명 |
$PSVersionTable | 다양한 버전 정보 출력 |
$home | 현재 사용자 홈 디렉토리 |
$pwd | 현재 작업 경로 |
$profile | 현재 사용자의 powershell 프로파일 스크립트 경로 |
$shellid | 현재 셸 ID |
1-2. 입력 및 파이프라인 관련
변수 | 설명 |
$_ | 파이프라인에서 현재 처리 중인 개체 |
$PSItem | $_와 동일 |
$args | 함수 또는 스크립트에 전달된 위치 기반 인수 배열 |
$input | 함수 또는 스크립트 블록에 파이프라인으로 전달된 입력 |
$MyInvocation | 현재 스크립트나 함수의 호출정보 |
$PSCmdlet | CmdletBase 제공 |
1-3. 오류 및 예외 처리 관련
변수 | 설명 |
$? | 마지막 명령의 성공 여부 (True/False) |
$LASTEXITCODE | 마지막 실행된 네이티브 명령어의 종료 코드 |
$Error | 오류 객체 배열, 최신 오류가 [0] |
$ErrorActionPreference | 오류발생 시 기본 동작 |
$PSBoundParameters | 함수 내에서 지정된 매개변수 딕셔너리 |
4. 세션 및 실행 컨텍스트 관련
변수 | 설명 |
$ExecutionContext | 실행 환경 제어 객체 |
$Host | 현재 Powershell 호스트 정보 |
$PID | 현재 powershell PID |
$null | NULL |
$true/$flase | 논리값 |
2. WMI Object
필자가 다른 포스팅에서 WMIC(Windows Management Instruction Commands)에 대해 다룬적이 있다. WMIC와 powershell WMI는 둘 모두 WMI에 기반을 두고있다. 다만 WMIC는 현재에도 여전히 동작하긴 하지만 windows 10 까지 사용되었던, 현재는 공식적으로 deprecated 된 기술이기에, 앞으로는 powershell로 넘어가는 것이 올바른 방향일 것이다. 사실 WMI Object 또한 더이상 권장되지 않는다. 대신 새로이 .Net Core를 기반으로 구현된 CIM Cmdlet 를 권장하고 있다. 그래도 이번 포스팅에서는 WMI와 CIM Cmdlet 두가지 다 정리할 계획이다.
2-1. Wmi cmdlet 목록 가져오기
# WMI Cmdlet 확인하기
Get-Command -Noun WMI*
Cmdlet | 주요 역할 | 기능 |
Get-WmiObject | 조회 | WMI 클래스/인스턴스를 정보 조회 |
Invoke-WmiMethod | 실행 | WMI 클래스/인스턴스 메소드 호출(프로세스 생성 종료 등) |
Set-WmiInstance | 수정/생성 | WMI 인스턴스를 수정하거나 새로 생성 |
Register-WmiEvent | 이벤트 구독 | WMI 이벤트 구독 및 트리거 감지(시스템 상태 변화 감지) |
Remove-WmiObject | 삭제 | WMI 인스턴스 삭제(프로세스 서비스 등) |
2-2. WmiObject cmdlet 목록 조회하기
#WMI Object 목록 가져오기
Get-WmiObject -List
# 특정 WMI Object 찾기
# findstr -i 옵션은 대소문자 구분x
Get-WmiObject -list | findstr -i 'network'
# where-object 절 활용
get-wmiobject -list | where-object { $_.name -match 'network'}
# namepsace 변경(기본 namespace는 root/cimv2)
get-wmiobject -NAMESPACE ROOT/WMI -list | where-object { $_.name -match 'network'}
2-3. WmiObject 활용 예제
시스템에 존재하는 NIC 중 현재 활성화된 NIC 만 골라서 출력하는 코드다.
Get-WmiObject -Class Win32_NetworkAdapter -Filter 'NetEnabled=True' | Select-Object NetConnectionID, @{Label='Speed'; Expression={"$($_.Speed / 1GB) Gb/s"}}
Get-WmiObject -Class Win32_NetworkAdapter -filter 'netenabled=true' | select netconnectionid,@{label='speed';expression={"$($_.speed/1000000000) Gb/s"}} | format-list
get-wmiobject -class win32_networkadapter | where-object { $_.NetEnabled -eq $true} | select-object *
파이프로 연결 후 select문에서 필요한 column만 선택 해 확인하거나 새로운 컬럼을 생성할수도 있다.
또 -filter 옵션을 사용하지 않고 pipe를 사용해 where-object라는 조건을 걸 수도 있다.
3. Cim Cmdlet
.net core로 새롭게 구현되어 사용이 권장되는 cmdlet 이다.
3-1. Cim Cmdlet 목록 조회하기
# get-command는 실행가능한 거의 모든 명령을 출력하는 기능
Get-Command -Module CimCmdlets
3-2. Cim Cmdlet 목록 조회하기
# 전체 조회
Get-CimClass
# 이름으로 필터링
Get-CimClass -ClassName *network*
3-3. Cim Cmdlet 활용 예제
문법은 약간 다르지만 출력하는 정보는 wmiobject와 같은것을 확인할 수 있다.
4. 시스템 정보 수집 스크립트 작성하기
파워쉘을 이용한다면 원격 접속이나 원격제어 레지스트리, 프로세스, 서비스, 계정 관리 등 윈도우 운영체제 상에서 지원하는 많은 작업들을 수행할 수 있지만 이번 포스팅에서는 운영체제 정보를 수집하는 스크립트를 작성해보겠다.
4-1. Locale, 시각 정보 수집
우리는 데이터 수집 전 항상 시각 정보를먼저 확인해야 한다. 이때 가장 중요한것은 시스템의 Locale정보다. 어느 시간대에 있는지, 즉 UTC 정보도 함께 수집해야한다는 의미다.
# Timezone 정보 출력
[system.timezoneinfo]::local
# 시각정보 출력하는 함수 (UTC 정보 포함)
function Get-LocalTimeWithUtcOffset {
$now = Get-Date
$offset = [System.TimezoneInfo]::Local.BaseUtcOffset
$sign = if($offset.Hours -ge 0) {"+"} else {"-"}
$tz = "UTC{0}{1:D2}{2:D2}" -f $sign, [math]::Abs($offset.Hours), [math]::Abs($offset.minutes)
return "{0} ({1})" -f $now.Tostring("yyyy-MM-dd HH:mm:ss"), $tz
}
4-2. 시스템 정보 수집 스크립트
앞서 우리가 win32_networkadapter 를 사용해 우리에게 필요한 정보만을 수집하거나 가공하였던 것처럼 다음 방법들에 대해서도 충분이 그러한 방법들을 적용할 수 있을 것이다.
# hostname 출력
hostname
# 현재 사용자 정보 출력
whoami
# 사용자 계정정보 출력
net user
# 공유리소스 확인
net share
# 현재 로그온 중인 사용자, 세션 정보 확인
[system.security.principal.windowsidentity]::getcurrent()
Get-CimInstance -class win32_logonsession
Get-CimInstance -class win32_LoggedonUser
query user
query session
qwinsta
# 컴퓨터 시스템 정보 출력
get-wmiobject -class win32_computersystem
systeminfo
# 운영체제 정보 출력
get-wmiobject -class win32_operatingsystem
# bios 정보 출력
get-wmiobject -class win32_bios
# cpu 정보 출력
get-wmiobject -class win32_processor
# IP 및 NIC 정보 등 네트워크 정보 출력
get-wmiobject -class win32_networkadapterconfiguration
get-wmiobject -class win32_networkadapter
get-NetIPAddress
ipconfig /all
# 스토리지 정보 출력
get-wmiobject win32_diskpartition
# 파티션 정보 출력
get-wmiobject win32_logicaldisk
# 프로세스 정보 출력
get-wmiobject win32_process | select *
get-process | select *
tasklist /V
# 서비스 정보 출력
get-wmiobject win32_service
Get-service
service
sc.exe query type= service
# 네트워크 연결 정보 수집
netstat -nao
# 예약 작업 확인
get-scheduledtask
schtasks
# 드라이버 정보 확인
driverquery
sc.exe query type= driver
5. 참고
WMI 작업 - PowerShell
PowerShell은 처음부터 WMI 작업을 위한 cmdlet을 제공했습니다.
learn.microsoft.com
Get-WmiObject (Microsoft.PowerShell.Management) - PowerShell
PowerShell 3.0부터 이 cmdlet은 Get-CimInstance대체되었습니다. Get-WmiObject cmdlet은 WMI 클래스의 인스턴스 또는 사용 가능한 WMI 클래스에 대한 정보를 가져옵니다. 원격 컴퓨터를 지정하려면 ComputerName 매
learn.microsoft.com
시스템 관리를 위한 샘플 스크립트 - PowerShell
예제 컬렉션은 PowerShell을 사용하여 시스템을 관리하기 위한 시나리오를 안내합니다. 참고: 이러한 예제의 대부분은 Windows에서만 작동합니다.
learn.microsoft.com
get-wmiobject 구문 예시
WMI Windows PowerShell 명령 클래스에 대한 관리되는 참조 - Win32 apps
WMI Windows PowerShell 명령 클래스에 대한 관리되는 참조
learn.microsoft.com
https://learn.microsoft.com/ko-kr/previous-versions//dd315295(v=technet.10)
Get-WmiObject
Get-WmiObject 아티클 01/12/2010 이 문서의 내용 --> WMI(Windows Management Instrumentation) 클래스 인스턴스 또는 사용 가능한 클래스에 대한 정보를 가져옵니다. 구문 Get-WmiObject [-Authority ] [-Amended] [-AsJob] [-Authe
learn.microsoft.com