IF 문
$ServiceName = "Hyper-V 가상 컴퓨터 관리"
$HostName = hostname
$Service = Get-Service -DisplayName $ServiceName -ErrorAction SilentlyContinue
If (-Not $Service){
$ServiceName + "는" + $HostName + "에 설치되지 않았습니다."
Write-Host "Hyper-V 서비스를 설치합니다."
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
} ElseIf($Service.Status -eq "Running"){
$ServiceName + "가 동작 중입니다."
} Else {
$ServiceName + "가 중지되었습니다."
Start-Service -Name $Service.Name
}
네이티브 DOS 명령인 hostName으로 현재 컴퓨터 이름을 가져와 변수에 저장
$Service = Get-Service -DisplayName $ServiceName -ErrorAction SilentlyContinue
에서는 'Hyper-V 가상 컴퓨터 관리' 라는 이름의 서비스를 찾아서 변수에 저장
If (-Not $Service)
부정 연사자인 -Not 에 의해 If문이 참이 되어 Hyper-V 서비스를 설치하는 구문이 실행
ElseIf($Service.Status -eq "Running"
서비스 상태가 실행 상태인지 확인
Else {
$ServiceName + "가 중지되었습니다."
Start-Service -Name $Service.Name
}
마지막으로 서비스가 중지된 경우 다시 시작시키는 구문을 실행
Switch 문
Switch 키워드 다음에 스위치를 사용하지 않으면 기본적으로 대소문자를 구분하지 않는다. 평가되는 값에 대해 정확한 일치를 평가하는 -exact 스위치가 사용된다.
구문 형식
Switch [-regex|-wildcard\-exact] [-casesensitive] (평가 되는 값)
{
조건1 {동작}
.....
Default {동작}
}
Switch문의 형식
옵션 |
설명 |
평가되는 값 |
- Switch ($Option)
- Switch (1,3), Switch("Red")
- Switch (1..7)
- Switch (Get-Service)
|
-regex |
평가되는 값에 대해 정규식 조건 매칭 |
-wildcard |
와일드카드 문자 조건 매칭 |
-exact |
정확한 일치 조건 |
-casesensitive |
대소문자 구분 |
-조건N |
|
예) 위도우의 논리 디스크 정보를 확인해 디스크 유형에 따라 정보를 표시
$drive = Get-CimInstance -ClassName Win32_LogicalDisk `
-Filter "DeviceID='C:'"
switch ($drive.DriveType) {
3 { Write "로컬 고정 디스크" }
5 { Write "광학 디스크 장치" }
Default { Write "기타 장치" }
}
Get-CimInstance 명령어
윈도우에서 시스템 전반의 자원에 대한 정보를 저장하는 CIM 리포지토리(일종의 데이터베이스)를 다루는 명령 중 하나.
switch 문의 평가되는 값 부분에 Get-Service를 실행한다.
실행 시점에 가져온 객체 컬렉션의 각 값($_)에 일치하는 조건 스크립트 블록을 평가해 동작을 수행한다.
switch (Get-Service)
{
{$_.status -eq "Running"}{"실행중인 서비스:"+$_.name}
{$_.status -eq "Stopped"}{"중단된 서비스:"+$_.name}
}
와일드카드 패턴 사용
와일드카드 패턴을 이용할 시 일치 여부를 비교하는 대상이 무엇인지 구문에 알려주는 매개변수를 지정해야 한다.
아래 예제는 컴퓨터 이름에 따라 메시지를 출력하는 예제이다.
만약 컴퓨터 이름이 SEOUL-CL1 이라면 "SEOUL-CL1*" "SEOUL*" "*1" 와 모두 일치하므로 3개의 스크립트 블록이 실행된다. 이처럼 Switch 문은 If문과 달리 첫 번째 일치 조건만 실행하지 않고 각각의 일치하는 스크립트 블록을 모두 실행한다.
#환경 변수에서 컴퓨터 이름을 가져온다,
$name = Get-Content Env:\COMPUTERNAME
#Switch 문 블록
switch -Wildcard ($name) {
"SEOUL-CL1*" {
Write-Host "이 컴퓨터는 클라이언트다."
}
"SEOUL*" {
Write-Host "이 컴퓨터는 SEOUL에 있다."
}
"*DC*" {
Write-Host "이 컴퓨터는 도메인 컨트롤러다."
}
"*1" {
Write-Host "첫 번째 컴퓨터다."
}
Default {
Write-Host "일치하는 내용이 없다."
}
}
만약 다중으로 일치하는 상황을 피하고자 한다면 Break 키워드를 사용하면 된다.
$name = Get-Content Env:\COMPUTERNAME
Switch -Wildcard ($name) {
"SEOUL-CL1*" {
Write "이 컴퓨터는 클라이언트다."
break
}
"SEOUL*" {
Write "이 컴퓨터는 BUSAN에 있다."
}
"*DC*" {
Write "이 컴퓨터는 도메인 컨트롤러다."
break
}
"*1" {
Write "첫 번째 컴퓨터다."
}
Default {
Write "일치하는 내용이 없다."
}
}
ForEach문
다수의 개체를 담고 있는 컬렉션을 열면서 한 번에 하나의 개체에 어떤 처리를 해야할 경우 사용
ForEach ($temp in $Collection)
{
#$temp에 대한 처리 구문
}
ForEach 문은 $Collection에 저장된 개체들을 임시 변수인 $temp에 하나씩 담아 스크립트 블록 내의 코드로 반복 처리한다.
아래 코드는 ComupterNames.txt 파일에 한 줄에 컴퓨터 이름을 하나씩 읽어서 출력하는 명령이다.
#컴퓨터 이름 컬렉션을 변수에 저장한다.
$ComputerNames = Get-Content ComputerNames.txt
#컬렉션의 컴퓨터 이름 목록을 하나씩 처리한다.
ForEach ($pcname in $ComputerNames) {
Write-Host "현재 컴퓨터 이름은 $pcname 입니다."
}
$Services = Get-Service
ForEach ($Service in $Services) {
Write-Host "현재 서비스는 $($Service.name) 입니다."
}
For 문
For ($num=0 ; $num -le 9 ; $num++) {
Write-Host "Computer $num"
}
#컬렉션(배열) 만들기
$fruits = @("사과","오렌지","수박","배","포도","딸기","바나나")
#컬렉션 처리
For ($i=0; $i -lt $fruits.Length; $i++) {
$fruits[$i]
}
# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_for?view=powershell-6
Get-Help about_For -ShowWindows
While문
#컬렉션(배열) 만들기
$fruits = @("사과","오렌지","수박","배","포도","딸기","바나나")
#컬렉션 처리
$i=0
While ($i -lt $fruits.Length) # lt : less then
{
$fruits[$i]
$i++
}
Do 문
Do-While 문을 사용한 메모장 프로그램 실행
# Start-Process : https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process?view=powershell-6
$NumOfNotepad=0
do
{
$NumOfNotepad++
$NotePadID=Start-Process -FilePath notepad
}
while ($NumOfNotepad -le 2)
Do-Until문
$NumOfNotepad=0
do
{
$NumOfNotepad++
$NotePadID=Start-Process -FilePath notepad
}
until ($NumOfNotepad -gt 2)
메모장의 개수가 3인 되는 순간 Do 문은 끝난다.
Break 와 Continue문
$NumOfShots = 0
while ($True)
{
$MovingTarget = (Get-Date).Second
if ($MovingTarget -eq $NumOfShots)
{
Write-Host "이동 목표를 맞추는데 사용된 슈팅 횟수(s):$NumOfShots"
Break
}
$NumOfShots++
}
다음 예제는 ForEach문을 사용해 현재 시스템의 프로세스 목록 중에서 물리 메모리를 250MB 이상 사용하는 프로세스만 출력하도록 한다.
$ProcessLists = Get-Process
foreach ($Process in $ProcessLists)
{
if (($Process.PM/1MB) -le 250)
{
Continue
}
Write-Output ($Process.Name+'은 250MB 이상의 메모리를 사용한다.')
}
* 실습
$NumOfNotepad=0
# 동적 배열 변수를 ArrayList 형식의 변수를 만듬
$PIDs = New-Object System.Collections.ArrayList
do
{
$NumOfNotepad++
$NotePadID=Start-Process -FilePath notepad -PassThru
# 실행된 메모장의 프로세스 ID를 가져와 배열에 추가
$PIDs.Add($NotePadID.Id)
}
while ($NumOfNotepad -le 3)
# 1초간 정지
Start-Sleep -Seconds 1
do
{
$NumOfNotepad--
# 배열에 저장된 프로세스 ID를 사용하여 메모장을 종료
Stop-Process -Id $PIDs[$NumOfNotepad]
}
until (0 -ge $NumOfNotepad)
# 배열의 모든 내용을 지움
$PIDs.Clear()