PowerShell 실용 명령어 모음 ── 일상 업무에서 자주 쓰는 작은 기능 늘리기

· 업데이트: · · PowerShell, Windows, 명령줄, 자동화, 업무 효율화, 기존 자산 활용

수정 이력(3건, 최종 수정 2026년 08월 02일)

이 글에 적용한 변경 사항의 기록입니다. 보관해 둔 수정 전 버전은 DOI가 부여된 고정 URL에서 읽을 수 있습니다.

글 맨 앞에 "이 글의 지식 맵" 절을 추가했습니다. 본문에서 다루는 개념과 그 관계를 요약, 그림, 상세 페이지 링크로 모은 것입니다. 본문의 주장은 바꾸지 않았습니다.
외부 리뷰(1283건) 대응으로 본문을 업데이트했습니다. 개별 변경 내용은 아래 이력을 참고하세요.
평면으로 나열돼 있던 레시피를 목적별로 나눈 지도 표를 추가하고, 장 번호와 대응시켰습니다. 이전 글과의 차이 정리, 일부 레시피의 출력 예와 쓰임새, 1페이지 치트시트도 함께 넣었습니다.
최초 공개
이 글을 인용하기(DOI: 10.5281/zenodo.21635286)

이 글은 Zenodo에 보관되어 있습니다. 항상 최신 버전으로 연결되는 DOI와 지금 보고 있는 버전에 고정된 DOI를 아래에 함께 제시합니다.

小村 豪 (2026). 「PowerShell 실용 명령어 모음 ── 일상 업무에서 자주 쓰는 작은 기능 늘리기」. 합동회사 코무라소프트. https://doi.org/10.5281/zenodo.21635286 https://comcomponent.com/ko/blog/powershell-practical-command-recipes/

DOI(최신 버전)
10.5281/zenodo.21635286
DOI(이 버전)
10.5281/zenodo.21635287

1. 가장 먼저 짚어야 할 것

PowerShell의 기초를 익혔다면, 다음에는 “자주 쓰는 작은 기능”을 늘려 가면 실무에서 쓰기 좋아집니다.

여기서 말하는 작은 기능은 짧은 alias가 아닙니다. 이 글에서는 lscat 같은 축약형이 아니라 Get-ChildItem, Get-Content, Select-String 같은 정식 명령 이름을 씁니다.

그 전제로, 다음 작업을 한 줄 또는 몇 줄의 명령으로 할 수 있게 합니다.

개수를 센다
합계 크기를 알아본다
중복을 없앤다
종류별로 집계한다
필요한 값만 꺼낸다
두 결과를 비교한다
로그의 앞뒤 행을 본다
클립보드로 보낸다
실행 결과를 저장하면서 화면에도 출력한다
환경 변수나 네트워크를 확인한다

PowerShell은 긴 스크립트를 쓰지 않아도 편리합니다. 먼저 “자주 쓰는 구성 요소”를 늘려, 일상 업무 안에서 조금씩 조합할 수 있게 합니다.

명령을 외우는 것보다, “이럴 때는 이 구성 요소를 쓰면 된다”를 떠올리는 편이 중요합니다.

또한 이 글에 나오는 코드는, 장 구성에 맞춰 주제별로 정리한 실행 가능한 샘플 세트(레시피 스크립트와 Pester 테스트)로 GitHub에 공개하고 있습니다.

powershell-practical-command-recipes - komurasoft-blog-samples (GitHub)

이전 글과의 차이

이 글은 PowerShell 명령의 기본 ── 먼저 익힐 조작과 안전한 사용법의 후속입니다. 역할은 다음과 같이 나눕니다.

  PowerShell 명령의 기본 이 글
목표 PowerShell을 다룰 수 있게 된다 꺼낸 결과를 세고, 모으고, 비교하고, 남길 수 있게 된다
중심 문법과 파이프라인, 명령을 찾는 방법 집계, 비교, 추출, 출력 구성 요소
CSV / JSON 읽고 쓰는 기본 읽은 결과를 조건으로 좁혀 집계하는 쪽
프로세스 / 서비스 / 이벤트 로그 목록을 가져오는 기본 가져온 목록을 종류별로 세고, 차이를 보는 쪽
변경 명령 안전하게 실행하는 순서 그 자체 그 순서에 넣는 조사·기록 명령

즉 이전 글은 “값을 꺼낼 수 있게 하는” 데까지이고, 이 글은 “꺼낸 값을 어떻게 다룰지”입니다.

Get-ChildItem, Get-Content, Import-Csv, Get-Service 같은 조회 명령의 기본과 실행 정책, .ps1 작성, 오류 처리는 이전 글에 있습니다. 이 글은 그것을 전제로 앞으로 나아갑니다. Format 계열을 마지막에 쓰는 것, Export-Csv -Encoding UTF8처럼 양쪽 글에 나오는 이야기도 있지만, 이 글에서는 “집계나 비교로 가져갈 때 어떻게 할지”라는 각도에서 다룹니다.

이 글의 지식 맵

이 글은 Measure-Object·Select-Object·Sort-Object·Group-Object·Compare-Object 등 PowerShell의 읽기 계열 cmdlet으로 결과를 세고, 중복을 제거하고, 종류별로 묶고, 비교하는 실무 레시피를 정리합니다. Format-Table은 화면 표시 전용 객체를 반환하므로 Export-Csv나 후속 명령에 넘기기 전에 쓰면 출력이 깨진다고 하며, CSV로 내보낼 때는 열을 고르는 Select-Object를 써야 한다고 합니다. Remove-Item과 같은 변경 계열 명령에 대해서는 대상을 Get 계열 명령으로 확인하고, Measure-Object로 건수를 세고, Export-Csv로 증적을 남기고, -WhatIf로 예행하는 순서를 거친 뒤에 실행하는 것을, 사고를 줄이는 안전한 운영으로 권장합니다.

PowerShell 실용 명령 모음의 지식 맵PowerShell의 읽기 계열 cmdlet들이 집계·서식·비교·증적의 각 역할로 연결되고, Format-Table이 화면 표시 전용이라는 점, 변경 계열 명령은 확인·집계·증적·예행을 거친 뒤에 실행해야 한다는 점을 보여주는 그림.이용한다이용한다이용한다이용한다이용한다이용한다이용한다이용한다이용한다이용한다이용한다이용한다의 후속이용한다이용한다이용한다이용한다보다 먼저 해야 한다사용은 비권장보다 먼저 해야 한다보다 먼저 해야 한다보다 먼저 해야 한다보다 먼저 해야 한다전제로 한다전제로 한다전제로 한다PowerShell안전한 변경 조작 절차(보기→세기→정리→남기기→예행→실행)Measure-ObjectSelect-ObjectSort-ObjectGroup-ObjectSelect-StringCompare-ObjectGet-FileHashTee-ObjectStart-TranscriptExport-CsvInvoke-RestMethodMeasure-CommandPowerShell 7Get-ErrorTest-NetConnectionGet-WinEventRemove-ItemFormat-Table/Format-List-WhatIf 파라미터

그림의 실선은 항상 성립하는 관계, 점선은 조건이 붙는 관계입니다(성립 조건은 상세 페이지의 관계별 설명에 적혀 있습니다). 관계 전체 목록(총 26건, 근거와 확신도 포함)과 주요 개념의 정의는 지식 맵 상세 페이지에 정리되어 있습니다(일본어). 데이터: JSON-LD / Turtle

2. 이번 글의 전제

전제는 다음 세 가지입니다.

  1. 명령 이름은 정식 이름으로 쓴다
  2. 조회용 명령을 중심으로 한다
  3. 변경 명령은 반드시 대상 확인이나 -WhatIf와 함께 생각한다

예를 들어 파일을 삭제하는 명령을 바로 외우기보다, 먼저 다음 흐름을 익히는 편이 안전합니다.

대상을 본다
  → 조건으로 좁힌다
  → 개수를 센다
  → 필요하면 CSV로 남긴다
  → 변경 예정을 확인한다
  → 실행한다

이 글에서는 삭제나 중지 같은 강한 조작보다 조사, 집계, 비교, 출력을 중심으로 다룹니다.

3. 자주 쓰는 명령 지도

이번에 쓰는 주요 명령입니다. 오른쪽 끝에 자세히 다루는 장을 넣었습니다.

하고 싶은 일 명령
개수나 합계를 알아본다 Measure-Object 4, 5
필요한 값만 꺼낸다 Select-Object -ExpandProperty 6
중복을 정리한다 Sort-Object -Unique 7
종류별로 집계한다 Group-Object 8
필요한 열만 내고, 계산 열을 만든다 Select-Object 9
정렬한다 Sort-Object 10
문자열을 검색한다 Select-String 12
두 결과를 비교한다 Compare-Object 14
해시 값을 계산한다 Get-FileHash 15
클립보드를 쓴다 Set-Clipboard / Get-Clipboard 16
화면과 파일 양쪽에 낸다 Tee-Object 17
작업 로그를 남긴다 Start-Transcript 18
네트워크 연결을 확인한다 Test-Connection / Test-NetConnection 26
처리 시간을 잰다 Measure-Command 28
오류 상세를 본다 Get-Error 31
각 요소를 처리한다 ForEach-Object 각 장에서 수시로

전부를 한 번에 외울 필요는 없습니다. “셀 때는 Measure-Object”, “모을 때는 Group-Object”, “비교할 때는 Compare-Object“처럼 목적과 세트로 외우는 것을 권합니다.

목적별 장 지도

4장부터 36장까지는 다음 덩어리로 나뉩니다. 읽고 싶은 곳부터 읽으면 됩니다.

범주 다루는 내용
집계·가공 4~11 개수, 합계, 최댓값·평균, 값 꺼내기, 중복 제거, 종류별 집계, 계산 열, 정렬, Format 계열의 위치
텍스트·로그 조사 12~14 문자열 검색과 앞뒤 행, 치환, 두 목록의 비교
파일·데이터 내용 15, 19, 20 해시 값 확인, CSV 좁히기, JSON 설정 값
출력·기록 16~18 클립보드로 보내기, 화면과 파일 동시 출력, 작업 로그
시스템 조사 21~25, 31 환경 변수, 프로필, 프로세스, 서비스, 이벤트 로그, 오류 상세
네트워크 26, 27 연결 확인, Web 응답
실행 방법 28~30 실행 시간 측정, 백그라운드 실행, 명령 기록
문법 확인 32 비교 연산자
그대로 쓰는 레시피 33, 34 실무 레시피 11개와, 변경 명령과 조합할 때의 주의
빠른 표 35 목적에서 떠올리기 위한 치트시트

“알아보고 싶은 일은 정해졌는데, 어떤 명령인지 떠오르지 않는다”면 35장의 빠른 표부터 들어가는 것이 가장 짧습니다.

4. 개수를 센다 ── Measure-Object

먼저 자주 쓰는 것이 개수를 세는 작업입니다.

현재 폴더에 있는 파일 수를 셉니다.

Get-ChildItem . -File | Measure-Object

하위 폴더까지 포함해 셀 경우입니다.

Get-ChildItem . -File -Recurse | Measure-Object

Measure-Object 결과의 Count가 개수입니다.

파일 크기 합계를 보려면 Length를 집계합니다.

Get-ChildItem . -File -Recurse |
  Measure-Object -Property Length -Sum

다만 이 상태로는 바이트 수라 사람이 읽기 어려우므로, GB 단위로 바꿉니다.

$size = Get-ChildItem . -File -Recurse |
  Measure-Object -Property Length -Sum

[math]::Round($size.Sum / 1GB, 2)

폴더 전체 크기를 대략 보고 싶을 때 편리합니다.

5. 최댓값·평균도 알아본다

Measure-Object는 합계뿐 아니라 최댓값과 평균값도 냅니다.

Get-ChildItem . -File |
  Measure-Object -Property Length -Sum -Average -Maximum -Minimum

파일 크기 편차를 볼 때 씁니다.

프로세스의 누적 CPU 시간을 합할 수도 있습니다. Get-ProcessCPU는 사용률이 아니라, 프로세스가 시작된 이후 사용한 CPU 시간(초)입니다.

Get-Process |
  Measure-Object -Property CPU -Sum

다만 이 값은 순간의 CPU 사용률이 아니라 누적값이므로, 실행 시점과 프로세스 가동 시간에 따라 달라집니다.

조사용으로 보기에는 충분하지만, 엄밀한 감시를 하려면 전용 감시 도구나 로그 설계도 필요합니다.

6. 값만 꺼낸다 ── Select-Object -ExpandProperty

Select-Object는 열을 고를 때 자주 씁니다.

Get-Process |
  Select-Object Name, Id, CPU

이것은 “Name, Id, CPU라는 열을 가진 객체”를 냅니다.

한편 값만 꺼내고 싶을 때는 -ExpandProperty를 씁니다.

Get-Process -Name notepad -ErrorAction SilentlyContinue |
  Select-Object -ExpandProperty Id

파일 이름만 꺼낼 때도 같습니다.

Get-ChildItem . -File |
  Select-Object -ExpandProperty Name

명령 결과를 다른 명령이나 텍스트 파일에 넘길 때는 -ExpandProperty가 편리합니다.

예를 들어 파일 이름 목록만 저장합니다.

Get-ChildItem . -File |
  Select-Object -ExpandProperty Name |
  Set-Content .\file-names.txt -Encoding UTF8

Select-Object NameSelect-Object -ExpandProperty Name은 비슷해 보이지만 결과 형태가 다릅니다.

Select-Object Name
  → Name이라는 열을 가진 표

Select-Object -ExpandProperty Name
  → Name의 값 자체

CSV로 만들려면 열로 남기는 편이 좋고, 다른 문자열 처리로 넘기려면 값만 있는 편이 다루기 쉽습니다.

7. 중복을 없앤다 ── Sort-Object -Unique

파일 확장자만 목록으로 보고 싶을 때입니다.

Get-ChildItem . -File |
  Select-Object -ExpandProperty Extension |
  Sort-Object -Unique

실행하면 .txt, .log, .csv처럼 중복을 뺀 확장자만 표시됩니다.

프로세스 이름 종류만 볼 수도 있습니다.

Get-Process |
  Select-Object -ExpandProperty ProcessName |
  Sort-Object -Unique

사용자 목록 CSV에서 부서명 목록만 꺼내는 예입니다.

Import-Csv .\users.csv |
  Select-Object -ExpandProperty Department |
  Sort-Object -Unique

“목록에 같은 값이 많아 보기 어렵다”면 먼저 Sort-Object -Unique를 떠올리면 됩니다.

8. 종류별로 집계한다 ── Group-Object

중복을 없애는 데 그치지 않고 “무엇이 몇 건인지”를 보려면 Group-Object를 씁니다.

확장자별로 파일 수를 셉니다.

Get-ChildItem . -File |
  Group-Object -Property Extension -NoElement |
  Sort-Object -Property Count -Descending

출력은 이 형태입니다. 건수와 확장자는 폴더 내용에 따라 달라지지만, 열 순서는 같습니다.

Count Name
----- ----
   42 .log
   18 .csv
    7 .txt
    3

Name이 비어 있는 행은 확장자가 없는 파일입니다.

-NoElement를 빼면 Group 열이 늘고, 그 그룹에 들어간 요소 자체가 표시됩니다.

Count Name  Group
----- ----  -----
   42 .log  {app-20260601.log, app-20260602.log, app-20260603.log...}
   18 .csv  {export-01.csv, export-02.csv, export-03.csv...}

건수만 볼 때 Group 열이 있으면 화면이 가득 차므로 -NoElement를 붙입니다. 반대로 그 그룹에 무엇이 들어 있는지 확인할 때는 붙이지 않습니다.

서비스 상태별로 셉니다.

Get-Service |
  Group-Object -Property Status -NoElement

이벤트 로그 수준별로 셉니다.

Get-WinEvent -LogName System -MaxEvents 500 |
  Group-Object -Property LevelDisplayName -NoElement

Group-Object는 조사 초반에 전체 그림을 잡을 때 맞습니다.

어느 확장자가 많은가
어느 상태의 서비스가 많은가
어느 오류 수준이 많은가
어느 부서의 데이터가 많은가

세부 내용을 보기 전에 먼저 분포를 보고 싶을 때 씁니다.

9. 필요한 열을 만든다 ── 계산한 열을 추가한다

파일 크기는 Length로 가져오지만 단위는 바이트입니다. 매번 바이트 수를 보기는 힘드니, MB나 KB로 바꾼 열을 만들면 편리합니다.

Get-ChildItem . -File |
  Select-Object Name, @{Name="SizeKB"; Expression={ [math]::Round($_.Length / 1KB, 1) }}, LastWriteTime

하위 폴더까지 포함해, 큰 파일 순으로 보는 예입니다.

Get-ChildItem . -File -Recurse |
  Sort-Object -Property Length -Descending |
  Select-Object -First 20 FullName, @{Name="SizeMB"; Expression={ [math]::Round($_.Length / 1MB, 2) }}, LastWriteTime

@{Name="..."; Expression={ ... }}는 계산한 열을 만드는 작성법입니다. 처음에는 조금 길어 보이지만 실무에서 자주 씁니다.

예를 들어 프로세스 메모리 사용량을 MB로 표시할 수 있습니다.

Get-Process |
  Sort-Object -Property WorkingSet -Descending |
  Select-Object -First 10 Name, Id, @{Name="MemoryMB"; Expression={ [math]::Round($_.WorkingSet / 1MB, 1) }}

보고서에 낼 때는 원래 Length보다 SizeMB 같은 열이 읽기 쉽습니다.

10. 최신순·오래된 순·큰 순으로 본다

PowerShell에서 정렬은 Sort-Object입니다.

최근에 갱신된 파일을 봅니다.

Get-ChildItem . -File |
  Sort-Object -Property LastWriteTime -Descending |
  Select-Object -First 10 Name, LastWriteTime

오래된 파일을 봅니다.

Get-ChildItem . -File |
  Sort-Object -Property LastWriteTime |
  Select-Object -First 10 Name, LastWriteTime

큰 파일을 봅니다.

Get-ChildItem . -File -Recurse |
  Sort-Object -Property Length -Descending |
  Select-Object -First 10 FullName, Length

이 세 가지는 자주 씁니다.

최신순 → LastWriteTime -Descending
오래된 순 → LastWriteTime
큰 순 → Length -Descending

로그 조사, 불필요 파일 정리, 디스크 용량 조사에서 자주 나오는 조합입니다.

11. Format 계열은 화면 표시의 맨 끝에만 쓴다

화면에서 보기 쉽게 하려면 Format-Table이나 Format-List를 씁니다.

Get-Process |
  Sort-Object -Property WorkingSet -Descending |
  Select-Object -First 10 Name, Id, WorkingSet |
  Format-Table -AutoSize

한 건의 상세를 볼 때는 Format-List가 편리합니다.

Get-Process -Id $PID |
  Format-List *

다만 Format-TableFormat-List는 “표시용”입니다.

CSV로 내기 전이나, 다음 명령으로 가공하기 전에는 쓰지 않는 편이 안전합니다.

# 피한다
Get-Process |
  Format-Table Name, Id |
  Export-Csv .\process.csv -NoTypeInformation

CSV로 내려면 Select-Object로 열을 고릅니다.

# 올바른 예
Get-Process |
  Select-Object Name, Id |
  Export-Csv .\process.csv -NoTypeInformation -Encoding UTF8

헷갈리면 다음처럼 생각합니다.

화면으로만 본다 → Format-Table / Format-List
나중에 쓴다      → Select-Object

12. 로그 검색을 조금 편하게 한다 ── Select-String

문자열 검색에는 Select-String을 씁니다.

Select-String -Path .\logs\*.log -Pattern "ERROR"

패턴을 여러 개 지정할 수도 있습니다.

Select-String -Path .\logs\*.log -Pattern "ERROR", "WARN", "FATAL"

앞뒤 행도 보려면 -Context를 씁니다.

Select-String -Path .\logs\*.log -Pattern "ERROR" -Context 2

해당 행의 앞뒤 2행도 함께 표시하므로, 오류의 전후 관계를 확인하고 싶을 때 편리합니다.

단순 문자열로 찾고 싶을 때는 -SimpleMatch를 씁니다.

Select-String -Path .\logs\*.log -Pattern "[ERROR]" -SimpleMatch

Select-String-Pattern은 보통 정규식으로 다룹니다. [. 같은 기호를 그대로 찾으려면 -SimpleMatch를 붙이는 편이 분명합니다.

대문자·소문자를 구분하고 싶을 때입니다.

Select-String -Path .\logs\*.log -Pattern "Error" -CaseSensitive

검색 결과를 CSV로 남길 수도 있습니다.

Select-String -Path .\logs\*.log -Pattern "ERROR" |
  Select-Object Path, LineNumber, Line |
  Export-Csv .\error-lines.csv -NoTypeInformation -Encoding UTF8

13. 문자열을 바꾼다

텍스트 일부를 바꾸려면 -replace를 씁니다.

"server01.example.com" -replace "\.example\.com$", ""

파일 내용을 바꿀 때는 원본에 바로 덮어쓰지 않는 편이 안전합니다. 먼저 다른 파일로 냅니다.

(Get-Content .\appsettings.json -Raw) -replace "localhost", "db01" |
  Set-Content .\appsettings.preview.json -Encoding UTF8

확인한 뒤에, 필요하면 원본 파일에 반영합니다.

설정 파일이나 일괄 치환에서는 대상이 너무 많으면 사고가 납니다. 먼저 Select-String으로 대상을 확인한 뒤 치환하면 안전합니다.

Select-String -Path .\appsettings.json -Pattern "localhost" -SimpleMatch

14. 두 결과를 비교한다 ── Compare-Object

Compare-Object는 두 목록의 차이를 보는 명령입니다.

언제 쓰나: 작업 전후로 구성이 바뀌지 않았는지 확인할 때, 두 PC에서 설정이나 설치된 소프트웨어 목록을 맞춰 볼 때, 운영과 검증에서 서비스 구성을 비교할 때 씁니다. “바뀌지 않았을 것”을 확인할 때 효과가 있습니다.

예를 들어 변경 전후 파일 이름 목록을 비교합니다.

Compare-Object `
  -ReferenceObject (Get-Content .\before.txt) `
  -DifferenceObject (Get-Content .\after.txt)

before.txta.log, b.log, c.log가 있고, after.txtb.log, c.log, d.log가 들어 있으면 출력은 이렇게 됩니다.

InputObject SideIndicator
----------- -------------
d.log       =>
a.log       <=

양쪽에 있는 b.logc.log는 기본값으로는 표시되지 않습니다. 표시되는 것은 차이뿐입니다.

SideIndicator의 의미는 다음과 같습니다.

표시 의미
<= 왼쪽, 즉 ReferenceObject에만 있다
=> 오른쪽, 즉 DifferenceObject에만 있다
== 양쪽에 있다. -IncludeEqual을 붙인 경우에 표시된다

화살표 방향은 ReferenceObject(왼쪽)와 DifferenceObject(오른쪽) 중 어느 쪽에 기울어 있는지로 읽으면 외우기 쉽습니다. 위 예라면 a.log는 왼쪽(변경 전)에만 있으므로 사라진 파일, d.log는 오른쪽(변경 후)에만 있으므로 늘어난 파일입니다.

폴더의 파일 이름 목록을 저장해 비교하는 예입니다.

Get-ChildItem .\before -File |
  Select-Object -ExpandProperty Name |
  Set-Content .\before-list.txt -Encoding UTF8

Get-ChildItem .\after -File |
  Select-Object -ExpandProperty Name |
  Set-Content .\after-list.txt -Encoding UTF8

Compare-Object `
  -ReferenceObject (Get-Content .\before-list.txt) `
  -DifferenceObject (Get-Content .\after-list.txt)

서비스 목록 변경을 볼 수도 있습니다.

Get-Service |
  Select-Object Name, Status |
  Export-Csv .\services-before.csv -NoTypeInformation -Encoding UTF8

변경 후에 한 번 더 냅니다.

Get-Service |
  Select-Object Name, Status |
  Export-Csv .\services-after.csv -NoTypeInformation -Encoding UTF8

비교합니다.

Compare-Object `
  -ReferenceObject (Import-Csv .\services-before.csv) `
  -DifferenceObject (Import-Csv .\services-after.csv) `
  -Property Name, Status

작업 전후 차이를 남겨 두면 조사와 보고가 쉬워집니다.

15. 파일 해시 값을 확인한다 ── Get-FileHash

다운로드한 파일이나 배포 파일이 같은지 확인할 때는 해시 값을 씁니다.

Get-FileHash .\installer.exe -Algorithm SHA256

폴더 안 파일을 한꺼번에 확인할 때입니다.

Get-ChildItem .\downloads -File |
  ForEach-Object { Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256 }

CSV로 남길 수도 있습니다.

Get-ChildItem .\downloads -File |
  ForEach-Object { Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256 } |
  Select-Object Path, Hash |
  Export-Csv .\hashes.csv -NoTypeInformation -Encoding UTF8

파일 이름만으로는 같아 보여도 내용이 다를 수 있습니다. 배포물, 백업, 이전 작업에서는 해시 값을 남겨 두면 확인하기 쉽습니다.

16. 클립보드로 보낸다 ── Set-Clipboard

언제 쓰나: 조사 결과를 문의 회신이나 장애 보고에 그대로 붙일 때, Excel에 붙여 표로 만들 때 씁니다. 파일을 만들어 열고 선택해 복사하는 절차를 통째로 줄입니다.

명령 결과를 메일이나 채팅에 붙이려면 클립보드로 보내는 편이 편리합니다.

Get-Service |
  Select-Object Name, Status |
  ConvertTo-Csv -NoTypeInformation |
  Set-Clipboard

클립보드 내용을 볼 때입니다.

Get-Clipboard

Excel에 붙이려고 탭 구분으로 만들려면 ConvertTo-Csv의 구분 문자를 탭으로 합니다.

Get-Process |
  Select-Object Name, Id, CPU |
  ConvertTo-Csv -NoTypeInformation -Delimiter "`t" |
  Set-Clipboard

잠시 결과만 공유하려면 매번 파일을 만드는 것보다 편합니다. 다만 기록으로 남기려면 Export-Csv로 파일에 저장합니다.

17. 화면에도 내고, 파일에도 남긴다 ── Tee-Object

결과를 화면에서 보면서 동시에 파일에도 남기려면 Tee-Object를 씁니다.

Get-Process |
  Sort-Object -Property WorkingSet -Descending |
  Select-Object -First 10 Name, Id, WorkingSet |
  Tee-Object -FilePath .\top-process.txt

Tee-Object는 파이프라인 결과를 두 방향으로 보냅니다.

화면에 낸다
파일에도 저장한다

조사 중에 “보면서 기록하는” 용도에 맞습니다. 다만 나중에 Excel로 열려면 Export-Csv가 다루기 쉽습니다.

Get-Process |
  Sort-Object -Property WorkingSet -Descending |
  Select-Object -First 10 Name, Id, WorkingSet |
  Export-Csv .\top-process.csv -NoTypeInformation -Encoding UTF8

화면용이면 Tee-Object, 표 데이터로 남기려면 Export-Csv로 생각하면 분명합니다.

18. 작업 로그를 남긴다 ── Start-Transcript

언제 쓰나: 운영 환경에서 작업할 때, 나중에 “무엇을 어떤 순서로 실행했는지”를 보고해야 하는 장면에서 씁니다. 장애 대응이나 유지보수 작업의 기록으로, 시작 전에 한 번 실행해 두는 것입니다.

일련의 조작을 기록하려면 Start-Transcript를 씁니다.

Start-Transcript -Path .\work-log.txt

이 뒤에 실행한 명령과 화면 출력이 기록됩니다.

종료합니다.

Stop-Transcript

조사 작업에서는 나중에 다음을 확인하고 싶어집니다.

어떤 명령을 실행했는가
어느 폴더에서 작업했는가
어떤 결과가 나왔는가
오류가 났는가

Start-Transcript를 쓰면 작업 메모를 빠뜨렸을 때의 보험이 됩니다. 다만 비밀번호나 토큰처럼 기록하면 안 되는 정보가 화면에 나오는 작업에서는 쓰기에 주의합니다.

19. CSV를 읽어 조건으로 본다

업무 데이터에서는 CSV가 자주 나옵니다.

예를 들어 다음과 같은 users.csv가 있다고 합니다.

Name,Department,Enabled
Suzuki,Sales,true
Tanaka,Accounting,false
Sato,Sales,true

읽습니다.

Import-Csv .\users.csv

부서가 Sales인 사람만 봅니다.

Import-Csv .\users.csv |
  Where-Object { $_.Department -eq "Sales" }

유효한 사용자만 다른 CSV로 냅니다.

Import-Csv .\users.csv |
  Where-Object { $_.Enabled -eq "true" } |
  Export-Csv .\enabled-users.csv -NoTypeInformation -Encoding UTF8

CSV 값은 문자열로 다루는 경우가 많으므로, true / false나 숫자를 비교할 때는 필요하면 형 변환을 생각합니다.

예를 들어 점수가 80 이상인 행만 볼 때입니다.

Import-Csv .\scores.csv |
  Where-Object { [int]$_.Score -ge 80 }

20. JSON 설정 값을 본다

JSON은 설정 파일이나 Web API에서 자주 씁니다.

$config = Get-Content .\settings.json -Raw | ConvertFrom-Json
$config

특정 값만 볼 수도 있습니다.

$config.Database.Host

값을 바꿔 다른 파일에 저장하는 예입니다.

$config.Database.Host = "db01"
$config |
  ConvertTo-Json -Depth 10 |
  Set-Content .\settings.updated.json -Encoding UTF8

JSON을 다룰 때는 Get-Content -Raw를 쓰는 경우가 많습니다. -Raw를 붙이면 파일 전체를 하나의 문자열로 읽으므로, 여러 줄 JSON을 다룰 때 이 편이 분명합니다.

21. 환경 변수를 본다

환경 변수는 앱 설정이나 경로 확인에서 자주 씁니다.

목록을 봅니다.

Get-ChildItem Env:

현재 사용자 이름을 봅니다.

$env:USERNAME

임시 폴더를 봅니다.

$env:TEMP

PATH를 보기 쉽게 나눕니다.

$env:PATH -split ";"

현재 PowerShell 세션에서만 환경 변수를 설정합니다.

$env:APP_MODE = "Development"

이 설정은 지금 연 PowerShell 안에서만 유효합니다.

사용자 환경 변수로 저장할 때는 다음처럼 합니다.

[Environment]::SetEnvironmentVariable("APP_MODE", "Development", "User")

환경을 바꾸는 조작이므로, 회사 PC나 운영 서버에서는 영향 범위를 확인한 뒤에 합니다.

22. 프로필을 확인한다

PowerShell에는 시작 시 읽어 들이는 프로필이 있습니다.

위치를 확인합니다.

$PROFILE

있는지 확인합니다.

Test-Path $PROFILE

만들 때입니다.

New-Item -ItemType File -Path $PROFILE -Force

메모장으로 엽니다.

notepad $PROFILE

자주 쓰는 설정이나 함수를 프로필에 적어 두면 편리합니다. 다만 복잡한 처리를 너무 많이 쓰면 PowerShell 시작이 느려지거나, 다른 환경에서 재현하기 어려워지므로, 처음에는 자주 쓰는 경로나 표시 설정 정도로 남기는 것을 권합니다.

23. 프로세스를 본다

프로세스 조사에서는 먼저 메모리 사용량이 큰 순으로 보는 경우가 많습니다.

Get-Process |
  Sort-Object -Property WorkingSet -Descending |
  Select-Object -First 10 Name, Id, @{Name="MemoryMB"; Expression={ [math]::Round($_.WorkingSet / 1MB, 1) }}

특정 이름으로 좁힙니다.

Get-Process -Name notepad -ErrorAction SilentlyContinue

프로세스를 중지할 때는 바로 실행하지 않고 -WhatIf로 확인합니다.

Stop-Process -Name notepad -WhatIf

문제가 없으면 실행합니다.

Stop-Process -Name notepad

운영 환경에서는 프로세스 중지가 업무에 영향을 줄 수 있습니다. 중지하기 전에 대상, 이용자, 복구 방법을 확인합니다.

24. 서비스를 본다

서비스 목록을 봅니다.

Get-Service

중지된 서비스만 볼 때입니다.

Get-Service |
  Where-Object { $_.Status -eq "Stopped" }

자동 시작인데 중지된 서비스를 찾습니다.

Get-Service |
  Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" } |
  Select-Object Name, DisplayName, Status, StartType

서비스를 다시 시작할 때도 먼저 대상을 확인합니다.

Get-Service -Name "Spooler"

-WhatIf로 미리 확인합니다.

Restart-Service -Name "Spooler" -WhatIf

서비스 조작은 영향이 크므로, 유지보수 시간과 복구 절차를 확인한 뒤에 실행합니다.

25. 이벤트 로그를 본다

Windows 조사에서는 이벤트 로그를 보는 장면이 자주 있습니다.

시스템 로그의 최근 100건을 봅니다.

Get-WinEvent -LogName System -MaxEvents 100 |
  Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message

오류와 경고만으로 좁힙니다.

Get-WinEvent -LogName System -MaxEvents 500 |
  Where-Object { $_.LevelDisplayName -in @("Error", "Warning") } |
  Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message

최근 24시간의 오류만 봅니다.

$start = (Get-Date).AddHours(-24)

Get-WinEvent -FilterHashtable @{ LogName = "System"; StartTime = $start } |
  Where-Object { $_.LevelDisplayName -eq "Error" } |
  Select-Object TimeCreated, ProviderName, Id, Message

조사 결과를 CSV로 남길 때입니다.

Get-WinEvent -LogName System -MaxEvents 500 |
  Where-Object { $_.LevelDisplayName -in @("Error", "Warning") } |
  Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message |
  Export-Csv .\system-events.csv -NoTypeInformation -Encoding UTF8

이벤트 로그는 건수가 많아지기 쉬우므로, -MaxEvents나 기간 지정으로 범위를 좁히는 것이 중요합니다.

26. 네트워크를 확인한다

연결 확인에는 Test-Connection을 씁니다.

Test-Connection example.com -Count 4

Windows에서 TCP 포트 연결을 확인할 때는 Test-NetConnection이 편리합니다.

Test-NetConnection example.com -Port 443

DNS 이름 확인을 할 때입니다.

Resolve-DnsName example.com

네트워크 조사에서는 다음처럼 원인을 나눕니다.

이름 확인이 되는가
IP까지 도달하는가
목적 포트가 열려 있는가
프록시나 방화벽의 영향이 없는가

PowerShell만으로 전부를 판단하지 말고, 원인 분리의 입구로 쓰면 편리합니다.

27. Web 결과를 본다

Web 페이지를 가져올 때는 Invoke-WebRequest를 씁니다.

Invoke-WebRequest https://example.com |
  Select-Object StatusCode, StatusDescription

JSON API 결과를 다룰 때는 Invoke-RestMethod가 편리합니다.

Invoke-RestMethod https://api.github.com/repos/PowerShell/PowerShell |
  Select-Object full_name, stargazers_count, forks_count

API 결과는 처음부터 PowerShell 객체로 다루는 경우가 많아, Select-ObjectWhere-Object와 조합하기 쉽습니다.

사내 API를 조사할 때도 먼저 조회용 GET부터 시작합니다.

자격 증명이나 토큰을 다룰 때는 화면 표시와 transcript 기록에 주의합니다.

28. 실행 시간을 잰다 ── Measure-Command

언제 쓰나: “이 처리를 야간 배치에 올려도 되는지”를 판단할 때, 작성법을 바꿔 빨라졌는지 비교할 때 씁니다. 감이 아니라 숫자로 결정할 수 있게 됩니다.

처리에 시간이 얼마나 걸리는지 알려면 Measure-Command를 씁니다.

Measure-Command {
  Get-ChildItem C:\Windows -File -Recurse -ErrorAction SilentlyContinue |
    Measure-Object
}

결과에는 TotalSecondsTotalMilliseconds가 들어 있습니다.

$result = Measure-Command {
  Get-ChildItem . -File -Recurse | Measure-Object
}

$result.TotalSeconds

스크립트를 빠르게 하려면 감이 아니라 시간을 재는 것이 중요합니다. 다만 파일 수, 디스크 상태, 네트워크 상태에 따라 결과가 달라지므로, 한 번의 결과만으로 판단하지 말고 몇 번 확인합니다.

29. 시간이 걸리는 처리를 뒤에서 돌린다 ── Start-Job

언제 쓰나: 큰 폴더 전체 검색이나 해시 계산처럼 몇 분 걸리는 처리를 돌리면서, 그동안 다른 조사를 진행하고 싶을 때 씁니다. 반대로 몇 초 만에 끝나는 처리를 Job으로 만들어도, 띄우는 수고가 더 큽니다.

시간이 걸리는 조사를 별도 Job으로 실행하려면 Start-Job을 씁니다.

$job = Start-Job -ScriptBlock {
  Get-ChildItem C:\Windows -File -Recurse -ErrorAction SilentlyContinue |
    Measure-Object
}

Job 상태를 봅니다.

Get-Job

결과를 받습니다.

Receive-Job $job

필요 없어진 Job을 삭제합니다.

Remove-Job $job

Start-Job은 편리하지만 처음부터 많이 쓸 필요는 없습니다. 먼저 보통으로 실행하고, 시간이 걸리는 처리만 Job으로 만들면 이해하기 쉽습니다.

30. 명령 기록을 쓴다

언제 쓰나: 시행착오 끝에 만든 명령을, 잘 된 뒤에 절차서나 스크립트에 옮길 때 씁니다.

과거에 실행한 명령을 보려면 Get-History를 씁니다.

Get-History

명령 줄만 보기 쉽게 합니다.

Get-History |
  Select-Object Id, CommandLine

특정 기록을 다시 실행합니다.

Invoke-History 12

기록은 편리하지만 위험한 명령도 다시 실행할 수 있습니다. Remove-Item이나 Stop-Process 같은 변경 명령을 기록에서 다시 실행할 때는 내용을 확인한 뒤에 실행합니다.

31. 오류 상세를 본다 ── Get-Error

PowerShell 7에서는 직전 오류를 자세히 보기 위해 Get-Error를 쓸 수 있습니다.

Get-Error

직전 오류 메시지만 보고 싶을 때입니다.

$Error[0].Exception.Message

오류가 났을 때는 화면의 빨간 글자만 보지 말고, 다음을 확인합니다.

어느 명령에서 실패했는가
어느 경로나 대상에서 실패했는가
권한 문제인가
파일이 없는가
네트워크나 잠금 문제인가

조사 결과를 남기려면 Start-TranscriptExport-Csv와 조합합니다.

32. 자주 쓰는 비교 연산자

Where-Object에서는 비교 연산자를 자주 씁니다.

연산자 의미
-eq 같다 $_.Status -eq "Running"
-ne 같지 않다 $_.Status -ne "Running"
-gt 보다 크다 $_.Length -gt 10MB
-ge 이상 $_.Length -ge 10MB
-lt 보다 작다 $_.Length -lt 10MB
-le 이하 $_.Length -le 10MB
-like 와일드카드 일치 $_.Name -like "*.log"
-match 정규식 일치 $_.Name -match "^app"
-in 값이 목록에 들어 있다 $_.Status -in @("Running", "Paused")
-contains 목록이 값을 포함한다 @("a", "b") -contains "a"

예입니다.

Get-ChildItem . -File |
  Where-Object { $_.Length -gt 10MB }
Get-Service |
  Where-Object { $_.Status -in @("Running", "Paused") }
Get-ChildItem . -File |
  Where-Object { $_.Name -match "\.log$" }

처음에는 -eq, -ne, -gt, -lt, -like만으로도 충분합니다. 익숙해지면 -match-in을 쓰면 조건을 쓰기 쉬워집니다.

33. 바로 쓰는 실무 레시피

여기부터는 실무에서 그대로 쓰기 쉬운 형태의 예입니다.

확장자별 파일 수를 본다

Get-ChildItem C:\Work -File -Recurse |
  Group-Object -Property Extension -NoElement |
  Sort-Object -Property Count -Descending

폴더 내용을 대략 파악하고 싶을 때 씁니다.

큰 파일 상위 20건을 본다

Get-ChildItem C:\Work -File -Recurse |
  Sort-Object -Property Length -Descending |
  Select-Object -First 20 FullName, @{Name="SizeMB"; Expression={ [math]::Round($_.Length / 1MB, 2) }}

디스크 용량 조사에서 자주 씁니다.

최근 24시간에 갱신된 파일을 본다

$since = (Get-Date).AddHours(-24)

Get-ChildItem C:\Work -File -Recurse |
  Where-Object { $_.LastWriteTime -ge $since } |
  Select-Object FullName, Length, LastWriteTime

장애 발생 뒤에 어떤 파일이 갱신됐는지 볼 때 씁니다.

ERROR가 들어 있는 로그 행을 CSV로 만든다

Select-String -Path C:\App\Logs\*.log -Pattern "ERROR" |
  Select-Object Path, LineNumber, Line |
  Export-Csv .\error-lines.csv -NoTypeInformation -Encoding UTF8

조사 결과를 공유하기 쉬워집니다.

ERROR의 앞뒤 2행을 본다

Select-String -Path C:\App\Logs\*.log -Pattern "ERROR" -Context 2

원인의 전후 관계를 보고 싶을 때 씁니다.

메모리 사용량이 큰 프로세스를 본다

Get-Process |
  Sort-Object -Property WorkingSet -Descending |
  Select-Object -First 10 Name, Id, @{Name="MemoryMB"; Expression={ [math]::Round($_.WorkingSet / 1MB, 1) }}

자동 시작인데 멈춘 서비스를 본다

Get-Service |
  Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" } |
  Select-Object Name, DisplayName, Status, StartType

시스템 로그의 오류를 CSV로 만든다

Get-WinEvent -LogName System -MaxEvents 500 |
  Where-Object { $_.LevelDisplayName -eq "Error" } |
  Select-Object TimeCreated, ProviderName, Id, Message |
  Export-Csv .\system-errors.csv -NoTypeInformation -Encoding UTF8

명령 결과를 클립보드로 보낸다

Get-Service |
  Select-Object Name, DisplayName, Status |
  ConvertTo-Csv -NoTypeInformation |
  Set-Clipboard

메일이나 채팅에 붙일 때 편리합니다.

작업 전후 파일 목록을 비교한다

Get-ChildItem C:\Work -File |
  Select-Object -ExpandProperty Name |
  Set-Content .\before.txt -Encoding UTF8

작업 후에 한 번 더 가져옵니다.

Get-ChildItem C:\Work -File |
  Select-Object -ExpandProperty Name |
  Set-Content .\after.txt -Encoding UTF8

비교합니다.

Compare-Object (Get-Content .\before.txt) (Get-Content .\after.txt)

폴더 합계 크기를 GB로 본다

$size = Get-ChildItem C:\Work -File -Recurse |
  Measure-Object -Property Length -Sum

[math]::Round($size.Sum / 1GB, 2)

34. 변경 명령과 조합할 때의 주의

여기까지의 대부분은 조회용이며, 이들만이면 비교적 부담 없이 시험할 수 있습니다. 한편 아래는 변경 명령입니다.

조작 명령
복사 Copy-Item
이동 Move-Item
삭제 Remove-Item
이름 변경 Rename-Item
프로세스 중지 Stop-Process
서비스 다시 시작 Restart-Service
환경 변수의 영구 설정 [Environment]::SetEnvironmentVariable()

변경 명령은 다음 순서로 씁니다.

1. Get 계열로 대상을 본다
2. Where-Object로 좁힌다
3. Select-Object로 대상 목록을 본다
4. Measure-Object로 개수를 센다
5. 필요하면 Export-Csv로 남긴다
6. -WhatIf를 쓸 수 있으면 미리 확인한다
7. 실행한다

예를 들어 오래된 .tmp 파일을 삭제할 때입니다.

먼저 대상을 봅니다.

$limit = (Get-Date).AddDays(-30)

$targets = Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse |
  Where-Object { $_.LastWriteTime -lt $limit }

$targets |
  Select-Object FullName, Length, LastWriteTime

개수를 셉니다.

$targets | Measure-Object

CSV로 남깁니다.

$targets |
  Select-Object FullName, Length, LastWriteTime |
  Export-Csv .\delete-targets.csv -NoTypeInformation -Encoding UTF8

삭제 예정을 확인합니다.

$targets | Remove-Item -WhatIf

문제가 없으면 실행합니다.

$targets | Remove-Item

이 흐름만 지켜도 사고는 꽤 줄어듭니다.

35. 외우는 방법

명령을 하나씩 외우려고 하면 힘드니, 목적별로 외우는 편이 쓰기 좋아집니다.

목적 떠올릴 명령
세고 싶다 Measure-Object
합계하고 싶다 Measure-Object -Sum
종류별로 보고 싶다 Group-Object
중복을 없애고 싶다 Sort-Object -Unique
필요한 값만 필요하다 Select-Object -ExpandProperty
열을 정리하고 싶다 Select-Object
큰 순으로 보고 싶다 Sort-Object -Descending
문자열을 찾고 싶다 Select-String
앞뒤를 보고 싶다 Select-String -Context
둘을 비교하고 싶다 Compare-Object
기록을 남기고 싶다 Export-Csv / Start-Transcript
화면에도 파일에도 내고 싶다 Tee-Object
클립보드로 보내고 싶다 Set-Clipboard
시간을 재고 싶다 Measure-Command
오류를 자세히 보고 싶다 Get-Error

1페이지 치트시트

인쇄해 옆에 두려고, 작성법까지 넣은 빠른 표로 만듭니다. 여기만으로 일상 업무의 대부분은 조립할 수 있습니다.

목적 그대로 쓰는 형태
파일 수를 센다 Get-ChildItem . -File \| Measure-Object
합계 크기를 GB로 본다 [math]::Round((Get-ChildItem . -File -Recurse \| Measure-Object -Property Length -Sum).Sum / 1GB, 2)
확장자별 건수 Get-ChildItem . -File \| Group-Object -Property Extension -NoElement \| Sort-Object -Property Count -Descending
큰 파일 상위 20건 Get-ChildItem . -File -Recurse \| Sort-Object Length -Descending \| Select-Object -First 20 FullName, Length
최근 24시간에 갱신된 것 Get-ChildItem . -File -Recurse \| Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-1) }
값만 꺼낸다 Get-Service \| Select-Object -ExpandProperty Name
중복을 없앤다 Get-Content .\list.txt \| Sort-Object -Unique
로그에서 ERROR를 찾는다 Select-String -Path .\logs\*.log -Pattern "ERROR"
ERROR의 앞뒤 2행을 본다 Select-String -Path .\logs\*.log -Pattern "ERROR" -Context 2
두 목록을 비교한다 Compare-Object -ReferenceObject (Get-Content .\before.txt) -DifferenceObject (Get-Content .\after.txt)
해시 값을 확인한다 Get-FileHash .\installer.exe -Algorithm SHA256
결과를 클립보드로 Get-Service \| Select-Object Name, Status \| ConvertTo-Csv -NoTypeInformation \| Set-Clipboard
화면에도 파일에도 낸다 Get-Process \| Tee-Object -FilePath .\out.txt
작업 로그를 시작한다 Start-Transcript -Path .\work.log
CSV를 조건으로 좁힌다 Import-Csv .\data.csv \| Where-Object { $_.Status -eq "NG" }
CSV로 남긴다 ... \| Export-Csv .\out.csv -NoTypeInformation -Encoding UTF8
메모리가 큰 프로세스 Get-Process \| Sort-Object WorkingSet -Descending \| Select-Object -First 10 Name, Id, WorkingSet
멈춘 자동 시작 서비스 Get-Service \| Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" }
이벤트 로그의 오류 Get-WinEvent -LogName System -MaxEvents 200 \| Where-Object { $_.LevelDisplayName -eq "Error" }
연결을 확인한다 Test-NetConnection -ComputerName example.local -Port 443
실행 시간을 잰다 Measure-Command { ... }
직전 오류를 자세히 본다 Get-Error

빠뜨리면 안 되는 순서

보기 → 세기 → 정리하기 → 남기기 → 미리 확인하기 → 실행하기

Format-TableFormat-List는 이 흐름의 맨 끝, 화면으로 볼 때만 씁니다. Export-Csv나 다음 명령에 넘기기 전에 끼우면 그다음이 깨집니다.

36. 정리

PowerShell은 스크립트를 쓸 수 있게 되면 강력합니다. 다만 실무에서 가장 자주 쓰는 것은, 의외로 작은 명령의 조합입니다.

센다
정렬한다
모은다
비교한다
찾는다
꺼낸다
저장한다
클립보드로 보낸다
작업 로그를 남긴다

이들만 되어도 일상 업무는 꽤 편해집니다. 처음부터 어려운 자동화를 목표로 할 필요는 없습니다. 먼저 조회용 명령으로 상황을 정확히 볼 수 있게 한 뒤, 필요할 때만 Copy-Item, Move-Item, Remove-Item, Restart-Service 같은 변경 명령을 씁니다.

PowerShell을 안전하게 쓰는 요령은 다음 순서입니다.

보기 → 세기 → 정리하기 → 남기기 → 미리 확인하기 → 실행하기

이 순서를 익히면 PowerShell은 “검은 화면에서 명령을 치는 것”이 아니라, 매일의 조사, 정리, 보고를 뒷받침하는 실용적인 도구가 됩니다.

같은 태그를 공유하는 최신 기사입니다. 더 가까운 주제로 지식을 넓힐 수 있습니다.

이 기사와 가까운 토픽 페이지입니다. 기사를 출발점 삼아 관련 서비스와 다른 기사로 이어집니다.

이 기사는 다음 서비스 페이지로 이어집니다. 가까운 입구부터 확인해 주세요.

자주 묻는 질문

이 기사 주제에 대해 상담 시 자주 나오는 질문을 모았습니다.

PowerShell에서 파일 개수나 합계 크기를 알아보려면 어떻게 하나요?
Get-ChildItem의 결과를 Measure-Object에 파이프로 넘깁니다. 개수는 결과의 Count 속성으로 확인할 수 있고, 하위 폴더까지 포함하려면 -Recurse를 붙입니다. 합계 크기는 Measure-Object -Property Length -Sum으로 집계하며, 바이트 수 그대로는 읽기 어려우므로 [math]::Round($size.Sum / 1GB, 2)처럼 GB 단위로 바꾸면 보기 쉽습니다. -Average나 -Maximum을 붙이면 평균값·최댓값도 한 번에 나옵니다.
Select-Object의 -ExpandProperty는 일반 지정과 무엇이 다른가요?
Select-Object Name은 "Name이라는 열을 가진 표(객체)"를 반환하지만, Select-Object -ExpandProperty Name은 "Name의 값 자체"를 반환합니다. CSV로 내보낼 때는 열로 남겨 두는 일반 지정이 맞고, 다른 명령이나 문자열 처리, 텍스트 파일에 값만 넘길 때는 -ExpandProperty가 다루기 쉽습니다. 목적에 따라 나눕니다.
Format-Table을 Export-Csv 앞에 쓰면 안 되는 이유는 무엇인가요?
Format-Table과 Format-List는 화면 표시용 명령입니다. 출력이 표시용 객체로 바뀌어 그 뒤의 CSV 출력이나 가공이 제대로 되지 않습니다. CSV로 내거나 다음 명령으로 가공할 때는 Select-Object로 열을 고른 뒤 Export-Csv에 넘깁니다. "화면으로만 볼 때는 Format 계열, 나중에 쓸 때는 Select-Object"로 기억하면 헤매지 않습니다.
Remove-Item 같은 변경 명령을 안전하게 쓰는 절차가 있나요?
바로 실행하지 않습니다. 먼저 Get 계열 명령으로 대상을 보고, Where-Object로 좁히고, Select-Object로 대상 목록을 확인한 뒤, Measure-Object로 개수를 세고, 필요하면 Export-Csv로 기록을 남깁니다. 그다음 -WhatIf를 쓸 수 있는 명령이면 미리 실행해 삭제·이동 예정을 확인하고, 문제가 없으면 실행합니다. 이 순서만 지켜도 사고는 꽤 줄어듭니다.

저자 프로필

기사 저자의 프로필 페이지입니다.

Go Komura

합동회사 코무라소프트 대표

Windows 소프트웨어 개발, 기술 상담, 장애 조사를 중심으로 재현이 어려운 장애 조사와 기존 자산이 남아 있는 프로젝트에 강점이 있습니다.

블로그 목록으로 돌아가기