Windows PowerShell 5.1과 PowerShell 7의 차이 ── 사내 스크립트 이행 실무 가이드

· · PowerShell, Windows, 이행, 자동화, 운영 개선, 스크립트, 기존 자산 활용

“서버에 PowerShell 7을 설치하면 지금 쓰는 스크립트가 망가지지 않을까요” “5.1인 채로 두면 문제가 될까요” ── 사내 운영 스크립트를 보유한 고객으로부터 이런 질문을 받는 일이 늘었습니다. Windows에 처음부터 들어 있는 PowerShell(5.1)과, 별도로 설치하는 PowerShell 7. 이름이 같다는 이유로 “버전을 올리면 교체된다”고 오해하기 쉽지만, 실제로는 공존하는 별개의 제품입니다.

이 관계를 제대로 이해하지 못한 채 7을 도입하면, “설치했는데 아무것도 바뀌지 않았다(작업은 여전히 5.1로 동작하고 있다)”거나, 반대로 “이행했더니 일본어 파일 연계가 문자 깨짐을 일으켰다” 둘 중 하나를 밟게 됩니다. 특히 후자는 일본어 환경 특유의 사고로, 원인은 기본 문자 인코딩의 차이에 있습니다.

이 글에서는 사내 스크립트를 보유한 정보시스템·운영 담당자를 대상으로, 5.1과 7의 관계와 차이를 구조부터 정리하고, 실제로 이행을 진행하는 절차를 판단표와 함께 정리합니다.

1. 먼저 결론

  • Windows PowerShell 5.1과 PowerShell 7은 별개의 제품으로, 사이드바이사이드로 공존합니다. 5.1은 Windows에 동봉되어 .NET Framework 위에, 7은 별도 설치되어 .NET 위에 구축되어 있으며, 7을 설치해도 5.1은 사라지지 않습니다.12
  • Microsoft는 5.1에 신기능을 추가하지 않습니다. 5.1의 지원은 Windows 본체의 라이프사이클에 연동되며, 개발의 중심축은 7입니다. 새로 작성하는 스크립트는 7을 기준으로 삼아야 합니다.13
  • 실행 파일이 다릅니다. 5.1은 powershell.exe, 7은 pwsh.exe입니다. 작업 스케줄러 등의 실행 명령을 고쳐 쓰지 않는 한, 기존 구조는 계속 5.1로 동작합니다.45
  • 기본 문자 인코딩이 다릅니다. 5.1은 명령어(cmdlet)마다 제각각이고(Out-File은 UTF-16LE, Get-Content는 ANSI 등), 7은 일률적으로 BOM 없는 UTF-8입니다. 일본어 환경 이행에서 가장 먼저 밟는 지뢰입니다.6
  • 7에서 동작하지 않는 모듈에는 Windows 호환 기능이 있습니다. Import-Module -UseWindowsPowerShell로 백그라운드의 5.1 프로세스에 읽어들여 원격 처리를 통해 사용할 수 있지만, 반환되는 것은 직렬화된 객체이며 메서드는 호출할 수 없습니다.7
  • #Requires -Version$PSVersionTable로 “어느 쪽에서 동작해야 할 스크립트인가”를 코드에 명시합니다. 예상하지 못한 버전에서 실행되어 조용히 망가지는 사고를, 실행 전에 막을 수 있습니다.89
  • 이행은 재고 조사 → 7에서 실행 테스트 → 실행 명령 갱신의 단계적 방식으로 진행합니다. 7의 도입은 MSI나 winget으로 실시하고, 업데이트 배포(Microsoft Update 경유로 할지)도 처음에 정해 둡니다.524

2. 5.1과 7은 어떤 관계인가 ── 대체가 아니라 공존

먼저 전체 그림을 표로 파악합니다.

항목 Windows PowerShell 5.1 PowerShell 7
입수 방법 Windows에 동봉1 별도 설치(MSI/winget 등)2
기반 .NET Framework 4.x5 .NET(7.4는 .NET 8.0 등)54
실행 파일 powershell.exe pwsh.exe4
설치 위치 $Env:windir\System32\WindowsPowerShell\v1.05 $Env:ProgramFiles\PowerShell\75
향후 개발 신기능 추가 없음1 개발의 중심축. LTS/Stable 릴리스 있음3
지원 기간 Windows 본체의 라이프사이클을 따름3 기반 .NET의 지원 정책을 따름3

7은 5.1을 대체하지 않고, 별도의 디렉터리에 설치되어 사이드바이사이드로 동작합니다. 모듈 저장 위치(PSModulePath)도 프로필도 이벤트 로그도 별도로 관리되며, 7 쪽의 PSModulePath에는 5.1의 모듈 경로도 포함되어 있기 때문에 7에서 기존 모듈의 상당수를 읽어들일 수 있습니다.52

“어느 쪽에 있는지”는 다음 두 줄로 언제든지 확인할 수 있습니다. $PSVersionTable은 PowerShell의 버전 정보를 보유하는 자동 변수입니다.9

# 자신이 어느 쪽 PowerShell에 있는지 확인한다
$PSVersionTable.PSVersion   # 5.1.x면 Windows PowerShell, 7.x면 PowerShell 7
$PSVersionTable.PSEdition   # Desktop = Windows PowerShell / Core = PowerShell 7

공식적인 위치도 명확합니다. Windows PowerShell은 Windows에 동봉되는 버전으로, Microsoft는 신기능에 의한 갱신을 실시하지 않으며, 지원은 사용 중인 Windows의 버전에 연동됩니다. 한편 PowerShell(7 계열)은 새로운 .NET 위에 구축되며, 릴리스마다 기반 .NET의 지원 정책에 따른 지원 기간이 설정됩니다.13 5.1이 당장 내일 사라지는 것은 아니지만, “앞으로 작성할 것” “앞으로 오래 사용할 것”의 기준은 7에 두어야 한다는 것이 실무의 결론입니다.

3. 가장 먼저 밟는 지뢰 ── 기본 인코딩 차이와 문자 깨짐

일본어 환경의 이행 트러블 중 가장 많은 것이 문자 깨짐입니다. 원인은 명확한데, 기본 문자 인코딩이 양쪽에서 다릅니다.6

조작 5.1의 기본값 7의 기본값
Out-File・리다이렉트(>) UTF-16LE(BOM 포함)6 BOM 없는 UTF-86
Set-Content / Add-Content ANSI(일본어 환경에서는 Shift_JIS)6 BOM 없는 UTF-8
Get-Content(BOM 없는 파일) ANSI6 BOM 없는 UTF-8
Export-Csv ASCII(일본어가 손실됨)6 BOM 없는 UTF-8
스크립트 자체의 해석(BOM 없음) ANSI 코드 페이지6 UTF-8
# 같은 한 줄이라도, 5.1과 7에서는 생성되는 파일의 바이트열이 다르다
'こんにちは' | Out-File -FilePath C:\temp\hello.txt
# 5.1에서 실행 → UTF-16LE(BOM 포함) 파일
# 7에서 실행   → BOM 없는 UTF-8 파일

이것이 실무에서 의미하는 바는 두 가지입니다.

첫째, Shift_JIS를 전제로 한 파일 연계는 7로 갈아탄 순간 읽기도 쓰기도 깨질 수 있습니다. 5.1의 Get-Content는 BOM 없는 파일을 ANSI(일본어 환경에서는 Shift_JIS)로 읽지만, 7은 UTF-8로 읽기 때문입니다. 대책은 모든 파일 입출력에서 -Encoding을 명시하는 것입니다. 7에서는 코드 페이지 번호(-Encoding 932)나 등록된 이름으로 지정할 수 있으며, 7.4 이후에는 ansi라는 값도 사용할 수 있습니다.6 CSV 처리에서의 구체적인 작성법은 동시 공개한 「PowerShell로 Excel・CSV 업무 처리를 자동화한다」에 정리했습니다.

둘째, 스크립트 파일 자체의 저장 형식입니다. BOM 없는 UTF-8로 저장된 일본어 주석이 포함된 스크립트를 5.1이 읽으면, ANSI로 잘못 해석하여 문자 깨짐이나 구문 오류가 발생합니다. 공식 문서의 권장대로 비ASCII 문자를 포함한 스크립트는 BOM 포함 UTF-8로 저장해 두면, 5.1과 7 어느 쪽에서도 올바르게 해석됩니다.6

4. 호환성 ── 7에서 동작하지 않는 것과 Windows 호환 기능의 실력

4.1. 무엇이 동작하지 않게 되는가

7은 대부분의 기존 모듈을 그대로 읽어들일 수 있지만5, 실리지 않는 것도 있습니다. 공식적으로 제시된 대표적인 예입니다.

  • 동봉되지 않게 된 모듈: PSWorkflow/PSWorkflowUtility(워크플로), PSScheduledJob, ISE용 모듈, Microsoft.PowerShell.LocalAccounts 등은 7에 포함되지 않습니다.4
  • 스냅인: 모듈 이전의 오래된 확장 형식인 스냅인은 7에서 지원되지 않습니다.4
  • .NET Framework에 밀착된 코드: 7은 기반 .NET이 다르기 때문에, .NET의 메서드를 직접 호출하는 스크립트는 동작이 달라질 수 있습니다.54
  • 세부적인 동작 변경: Export-Csv#TYPE 행을 기본으로 출력하지 않게 되었고, Group-Object는 그룹이 정렬되어 반환되는 등, 출력에 의존하는 스크립트가 영향을 받는 변경이 있습니다.4

반대 방향의 비호환성도 있습니다. 삼항 연산자나 ForEach-Object -Parallel7에서 추가된 구문・기능을 사용한 스크립트는 5.1에서는 동작하지 않습니다.5 “어느 쪽에서도 동작하도록 작성한다”와 “어느 쪽에서 동작시킬지 명시한다” 중 어느 것으로 할지를 스크립트마다 정할 필요가 있는 셈입니다.

Microsoft 제품 모듈의 대응 상황은 공식 모듈 호환성 페이지에서 확인할 수 있습니다.10

편집 환경(ISE)의 이행 방향도 함께 정해 둡니다. Windows PowerShell ISE는 Windows에서 삭제될 예정은 없으며, 보안 및 우선순위가 높은 수정도 계속되지만, 신기능 개발은 종료되었고 대응하는 것은 PowerShell 5.1 이전뿐입니다.11 즉, 7에서 동작시킬 스크립트를 ISE에서 작성하고 실행하는 운용은 성립하지 않습니다. 공식이 안내하는 이행처는 Visual Studio Code와 PowerShell 확장 기능으로, 확장 기능을 설치하면 통합 콘솔에서 사용할 PowerShell 버전을 전환할 수 있습니다(추가 경로도 설정으로 더할 수 있습니다). ISE에 익숙한 사람을 위해 “ISE의 조작감을 VS Code에서 재현하는” 가이드도 마련되어 있으므로, 전환 안내는 거기서부터 시작하는 것이 빠릅니다.11 정보시스템 현장은 ISE 이용자가 많으므로, 스크립트 이행 계획과 편집 환경 전환은 같은 시점에 함께 안내하십시오.

4.2. Windows 호환 기능(-UseWindowsPowerShell)의 구조와 제약

7에는 5.1에서만 동작하는 모듈을 위한 Windows 호환 기능이 있습니다.

# 7에 대응하지 않는 모듈을 호환 기능을 통해 읽어들인다(공식 문서의 예)
Import-Module -Name ScheduledTasks -UseWindowsPowerShell

구조는 원격 처리(리모팅)의 응용입니다. 백그라운드에서 Windows PowerShell 5.1 프로세스가 시작되어 WinPSCompatSession이라는 세션에 모듈이 로드되고, 7 쪽에는 암묵적 원격 처리로 생성된 프록시 모듈이 임포트됩니다. System32 아래의 5.1 전용 모듈은 이름 지정이나 명령 자동 검색에서도 암묵적으로 이 구조를 통해 로드됩니다.7

그림으로 나타내면 두 프로세스의 관계가 명확해집니다.

powershell.exe ── 뒤에서 실행되는 5.1 프로세스pwsh.exe ── PowerShell 7 프로세스명령 호출을 전달결과직렬화된 값의 사본만 돌아옴메서드는 호출할 수 없음WinPSCompatSession호환 기능으로 읽어들인 모든 모듈이하나의 런스페이스를 공유한다5.1에서만 동작하는 모듈 본체스크립트 본체프록시 모듈암묵적 원격 처리로 생성된 입구.본체가 아님

그림에서 보듯이, 7 쪽에 있는 것은 모듈 본체가 아니라 입구뿐입니다. “7을 설치하면 전부 7에서 동작한다”가 아니라 “7이 5.1에 부탁하여 결과의 사본을 받고 있다”는 것이 실태이며, 뒤에서 설명할 제약은 모두 이 구조에서 비롯됩니다.

편리하지만, 제약을 이해하지 못한 채 사용하면 조용히 망가집니다. 공식적으로 명시된 제약은 다음과 같습니다.7

  • 주고받는 것은 직렬화된 값이며, 원시(raw) 객체가 아닙니다. 반환된 객체의 메서드는 호출할 수 없고, 속성의 스냅숏만 손에 들어옵니다.
  • 로컬 Windows에서만 동작하며, Windows PowerShell 5.1이 필요합니다.
  • 호환 기능으로 로드한 모든 모듈이 하나의 런스페이스(하나의 5.1 프로세스)를 공유합니다.
  • 일부 모듈(PSScheduledJob 등)은 기본값으로 로드가 거부됩니다.

“취득한 결과의 메서드를 호출한다”, “파이프라인 도중에 원시 객체가 필요하다” 같은 처리는 호환 기능으로는 성립하지 않습니다. 이 경우 파이프라인 전체를 5.1 쪽에서 실행하여 최종 결과만 받는 작성법도 가능하지만7, 복잡해질 바에는 그 처리만 5.1인 채로 남겨두는 편이 유지보수하기 쉽다는 것이 실무 감각입니다.

5. 방어적으로 작성한다 ── #Requires와 버전 분기

이행 기간 중에는 “어느 쪽에서 실행될지 알 수 없는” 상태가 반드시 발생합니다. 예상하지 못한 버전에서 동작하다가 도중에 망가지는 것이 최악이므로, 스크립트 쪽에 방어 장치를 넣습니다.

#Requires 문을 작성해 두면, 조건을 충족하지 않는 PowerShell에서는 스크립트가 실행되기 전에 거부됩니다.8

#Requires -Version 7.0
# 이 스크립트는 7 전용(ForEach-Object -Parallel 등을 사용).
# powershell.exe(5.1)로 실행된 경우, 여기서부터는 일절 실행되지 않는다

반대로 5.1 전용 스크립트에는 #Requires -PSEdition Desktop을 작성합니다. Desktop이 5.1 계열, Core가 7 계열의 에디션 이름입니다.89

어느 쪽에서도 동작하는 스크립트에서 일부만 동작을 바꾸고 싶은 경우에는, $PSVersionTable로 실행 시에 분기합니다.9

# 5.1과 7 양쪽을 모두 지원하는 스크립트에서, 버전 차이가 있는 처리만 분기한다
if ($PSVersionTable.PSVersion.Major -ge 6) {
    $enc = 932            # 7: 코드 페이지 번호로 Shift_JIS를 지정할 수 있다
} else {
    $enc = 'Default'      # 5.1: Default = 시스템의 ANSI 코드 페이지
}
Get-Content -LiteralPath $path -Encoding $enc

포인트는 이 명시를 “이행이 끝난 뒤”가 아니라 “재고 조사 시점에” 넣는다는 것입니다. #Requires 행이 한 줄 있는 것만으로, 그 스크립트가 어느 쪽 세계의 주민인지 누구나 알 수 있습니다.

6. 이행을 진행하는 방법 ── 재고 조사부터 작업 스케줄러 갱신까지

실제 이행은 다음 순서로 진행합니다. 일괄 전환은 사고의 원인이 되므로, 단계적 이행이 원칙입니다.

절차 1: 재고 조사. 스크립트 저장소와 작업 스케줄러에서, 동작 중인 .ps1과 실행 명령을 모두 파악합니다.

# 작업 스케줄러에서, PowerShell을 실행하는 작업을 모두 찾아낸다
Get-ScheduledTask | ForEach-Object {
    foreach ($action in $_.Actions) {
        # cmd.exe /c powershell ... 같은 간접 실행도 걸러내기 위해, 실행 파일과 인수 양쪽을 확인한다
        if ("$($action.Execute) $($action.Arguments)" -match 'powershell|pwsh') {
            [pscustomobject]@{
                TaskPath  = $_.TaskPath        # 작업 이름은 폴더 내에서만 고유하므로, 경로도 함께 기록한다
                TaskName  = $_.TaskName
                Execute   = $action.Execute    # powershell.exe인지 pwsh.exe인지
                Arguments = $action.Arguments
            }
        }
    }
} | Export-Csv -Path .\ps-tasks.csv -NoTypeInformation -Encoding UTF8

완성되는 ps-tasks.csv는 4개의 열입니다. 열의 의미와 서식 예를 들겠습니다(값은 형식의 예이며, 실제 내용은 환경마다 다릅니다).

내용 값의 예
TaskPath 작업의 폴더. 작업 이름은 폴더 내에서만 고유함 \\Contoso\Batch\
TaskName 작업 이름 DailyReport
Execute 실행되는 실행 파일 powershell.exe / C:\Program Files\PowerShell\7\pwsh.exe / cmd.exe
Arguments 인수 문자열 -NoProfile -ExecutionPolicy RemoteSigned -File C:\scripts\daily-report.ps1

이 CSV는 다음 세 가지를 보기 위해 만듭니다. Execute가 powershell.exe인 행은 아직 5.1로 동작하는 작업, 즉 이행 대상입니다. Execute가 cmd.exe인 행은 Arguments 안에 PowerShell 실행이 묻혀 있으므로 내용을 열어 확인합니다. 그리고 Arguments에 -File-Command도 나오지 않는 행은 위치 지정 그대로 넘기는 호출이므로, 절차 5에서 pwsh로 교체할 때 해석이 달라집니다(이유는 절차 5). 이 세 가지를 구분하는 것만으로 이행 계획의 분모가 정해집니다.

절차 2: 7의 도입. MSI 패키지(배포 관리 도구를 통한 전개에 적합) 또는 winget으로 설치합니다.52

어떤 버전을 어떻게 설치할지는 다음 기준으로 정합니다.32

논점 선택지 판단 기준
어떤 버전인가 LTS / Stable 업무 서버는 LTS. LTS는 .NET의 LTS에 대응하는 버전으로, 업데이트는 중대한 보안 수정과 유지 관리로 한정되어 기존 워크로드에 대한 영향이 최소화되도록 설계되어 있습니다. Stable은 신기능을 포함하는 대신, 다음 LTS가 나온 뒤 약 6개월 만에 지원이 종료됩니다3
클라이언트 단말 winget 공식이 Windows 클라이언트에서의 권장 방법으로 제시하고 있습니다2
서버·다수 전개 MSI 패키지 Windows Server와 기업 전개에 최적이라고 명시되어 있습니다. 커맨드라인 속성으로 업데이트 경로까지 지정할 수 있습니다2
MSIX(스토어) 버전 주의 사용자 단위 설치로 전체 사용자용으로 만들 수 없고, 앱 샌드박스로 인해 WSMan 경유의 PowerShell Remoting을 사용할 수 없는 등의 제한이 있습니다. 서버에는 적합하지 않습니다2
# winget을 통한 설치. 업데이트도 winget upgrade로 같은 경로를 탄다
winget install --id Microsoft.PowerShell --source winget

# MSI 패키지로 설치하고 싶은 경우(서버・배포 관리 도구용)
winget install --id Microsoft.PowerShell --source winget --installer-type wix

winget 자체에도 전제 조건이 있습니다. 7.6.0의 winget 패키지 이후, winget install --id Microsoft.PowerShell기본으로 MSIX 패키지를 설치하는 방식으로 바뀌었기 때문에, MSI를 원하는 경우 위와 같이 --installer-type wix를 붙입니다. 또한 winget은 Windows Server 2022 이전에서는 사용할 수 없습니다(Windows Server 2025의 데스크톱 경험판에는 동봉되어 있습니다). 서버군에 대한 전개는 MSI를 전제로 계획하는 것이 무난합니다.2

업데이트 운용도 처음에 정합니다. 7.2 이후의 MSI에는 Microsoft Update를 통해 업데이트를 받는 옵션(기본으로 활성화)이 있어, WSUS나 구성 관리 도구의 일반적인 업데이트 흐름에 태울 수 있습니다.4 관리되지 않은 상태로 방치되어 오래된 7이 계속 남는 것이 가장 나쁜 패턴입니다.

절차 3: 7에서의 실행 테스트. 재고 조사한 각 스크립트를 pwsh로 실행하여, 동작하는지・출력 파일이 깨지지 않았는지를 확인합니다. 7은 5.1과 공존하므로, 운영 중인 작업을 멈추지 않고 테스트할 수 있는 것이 사이드바이사이드 설계의 장점입니다.2 오류가 발생하면 4장의 호환성 문제(모듈, .NET API, 동작 변경)를 구분하여 살펴봅니다.

“동작했다”의 기준을 정해 두지 않으면 테스트가 끝나지 않으므로, 합격 조건을 체크리스트로 만들어 둡니다.

  • pwsh -NoProfile -File <스크립트>가 끝까지 실행되고, $LASTEXITCODE가 0으로 종료된다
  • 오류 스트림에 아무것도 출력되지 않는다(예상된 경고는 내용을 확인하고 허용한다)
  • 의존 모듈이 모두 7에서 로드된다(Import-Module이 통과한다. 호환 기능으로 떨어지지 않았는지도 확인한다)
  • 출력 파일의 내용이 5.1판과 일치한다(아래의 Compare-Object)
  • 출력 파일의 인코딩이 수신 측이 기대하는 대로다(3장. Shift_JIS를 전제로 한 연계처가 있다면 필수)
  • 변경계 처리는 -WhatIf로 대상이 5.1일 때와 같은지 확인했다
  • 실행 시간이 극단적으로 늘어나지 않았다(호환 기능을 경유하면 느려지는 경우가 있다)

출력 대조는 같은 스크립트를 5.1과 7 양쪽에서 실행하여 차이를 비교하는 것이 확실합니다.

# 5.1과 7에서 같은 스크립트를 실행하고, 출력 파일을 비교한다
& "$Env:windir\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -File .\daily-report.ps1
Move-Item .\report.csv .\report-51.csv -Force
& "$Env:ProgramFiles\PowerShell\7\pwsh.exe" -NoProfile -File .\daily-report.ps1
Move-Item .\report.csv .\report-7.csv -Force

# 줄 단위 차이. 실행 일시 등 매번 바뀌는 열이 있다면, 그 열을 제외한 뒤 비교한다
Compare-Object (Get-Content .\report-51.csv) (Get-Content .\report-7.csv)

# 바이트 단위로 일치하는지까지 확인한다(BOM이나 줄바꿈 코드의 차이는 여기서 드러난다)
(Get-FileHash .\report-51.csv).Hash -eq (Get-FileHash .\report-7.csv).Hash

차이가 발견되면, 먼저 “값이 다른” 것인지 “겉보기는 같은데 바이트열만 다른” 것인지를 구분합니다. Compare-Object에서는 차이가 나지 않고 Get-FileHash만 불일치한다면, 원인은 인코딩이나 줄바꿈 코드의 차이(3장)입니다. 이행 완료의 정의는 “7에서 예외 없이 끝나는 것”이 아니라, “5.1일 때와 같은 산출물이 나오는 것”에 두십시오.

절차 4: 어느 쪽에서 동작시킬지 명시. 테스트를 통과한 것에는 #Requires -Version 7.0을, 5.1에 남길 것에는 #Requires -PSEdition Desktop을 추가합니다(5장).

절차 5: 실행 명령 갱신. 작업 스케줄러의 작업을 고쳐 씁니다. 이 부분을 잊으면 “7로 이행했다고 생각했는데 계속 5.1로 동작하고 있는” 상황이 발생합니다.

# 변경 전(5.1로 실행됨):
#   powershell.exe -NoProfile -ExecutionPolicy RemoteSigned -File C:\scripts\daily-report.ps1
# 변경 후(7로 실행됨):
#   "C:\Program Files\PowerShell\7\pwsh.exe" -NoProfile -File C:\scripts\daily-report.ps1

또한 pwsh.exe는 첫 번째 위치 지정 매개변수가 -Command에서 -File로 바뀌었습니다. powershell.exe -Command "..."에 해당하는 호출을 기계적으로 치환하면 해석이 달라지므로, -File / -Command를 반드시 명시하십시오.4

실행 정책이나 스크립트 서명의 취급은 동시 공개한 「PowerShell의 실행 정책과 스크립트 서명」을, 배치 파일(.bat)로부터의 이행 판단은 「그 배치 파일, PowerShell로 이전해야 할까」를 참조하십시오.

7. 실무의 정석(판단표)

논점 선택지 판단 기준
신규 스크립트의 기준 5.1 / 7 원칙적으로 7. 5.1은 신기능 추가 없이 현상 유지이며, 개발의 중심축은 713
기존 스크립트의 이행 일괄 전환 / 단계적 이행 재고 조사 → 7에서 테스트 → 통과한 것부터 실행 명령 갱신. 사이드바이사이드이기 때문에 단계적 이행이 가능5
5.1 전용 모듈이 있다 이행을 포기한다 / -UseWindowsPowerShell / 그 처리만 5.1에 남긴다 호환 기능은 직렬화 제약(메서드 불가)을 이해한 뒤에. 복잡해진다면 5.1에 남기는 쪽이 유지보수하기 쉬움7
버전 명시 아무것도 하지 않는다 / #Requires 모든 스크립트에 #Requires나 실행 시 점검을 넣는다. 예상하지 못한 버전에서의 실행을 실행 전에 막는다8
파일 입출력 기본값에 맡긴다 / -Encoding 명시 항상 명시. 5.1과 7의 기본값 차이로 인한 문자 깨짐을 구조적으로 방지한다6
7의 업데이트 운용 수동으로 다시 설치한다 / MSI의 Microsoft Update 연계나 winget 업데이트 경로를 정한 뒤 배포한다. 방치된 오래된 7이 가장 위험함42

8. 정리

  • 5.1과 7은 별개의 제품으로, 사이드바이사이드로 공존합니다. 7을 설치해도 기존 구조는 망가지지 않지만, 반대로 실행 명령을 바꾸지 않는 한 아무것도 이행되지 않습니다.
  • 5.1은 신기능 추가 없음・지원은 Windows 본체에 연동되는 현상 유지 모드이며, 7이 개발의 중심축입니다. 신규는 7을 기준으로 작성합니다.
  • 일본어 환경의 가장 큰 지뢰는 기본 인코딩의 차이(5.1은 제각각, 7은 BOM 없는 UTF-8)입니다. 입출력의 -Encoding 명시와, 스크립트의 BOM 포함 UTF-8 저장으로 방지합니다.
  • 7에서 동작하지 않는 모듈은 Windows 호환 기능으로 구제할 수 있지만, 직렬화된 값만 반환되는 제약이 있습니다. 무리라면 해당 처리만 5.1에 남깁니다.
  • #Requires와 $PSVersionTable로 “어느 쪽에서 동작하는 스크립트인가”를 코드에 명시하고, 예상하지 못한 버전에서의 실행을 막습니다.
  • 이행은 재고 조사 → 7 도입(MSI/winget) → 실행 테스트 → #Requires 부여 → 작업 스케줄러의 실행 명령 갱신, 의 단계적 방식으로 진행합니다.

관련 글

관련 상담 영역

합동회사 코무라소프트는 사내 스크립트 자산의 재고 조사와 PowerShell 7로의 단계적 이행 계획·실시, 5.1 전용 모듈에 의존하는 처리의 구분, “이행했더니 문자가 깨졌다·동작하지 않게 되었다” 같은 문제의 조사를 다루고 있습니다.

참고 링크

  1. Microsoft Learn, What is Windows PowerShell?. Windows PowerShell과 PowerShell이 별개의 제품이라는 점, Windows PowerShell은 Windows에 동봉되어 .NET Framework 위에 구축되며 최신판이 5.1이라는 점, Microsoft가 신기능에 의한 갱신을 실시하지 않으며 지원이 사용 중인 Windows의 버전에 연동된다는 점에 대해.  2 3 4 5 6

  2. Microsoft Learn, Install PowerShell 7 on Windows. PowerShell 7이 Windows PowerShell 5.1을 대체하지 않고 새로운 디렉터리에 설치되어 사이드바이사이드로 실행된다는 점, 기본 설치 위치가 $Env:ProgramFiles\PowerShell\7이라는 점, winget・MSI 등의 설치 방법에 대해.  2 3 4 5 6 7 8 9 10 11 12

  3. Microsoft Learn, PowerShell Support Lifecycle. PowerShell 7에 LTS와 Stable의 릴리스 구분이 있으며, 지원 종료일이 기반 .NET의 지원 정책을 따른다는 점, Windows PowerShell은 Windows의 구성 요소로서 Windows의 지원 라이프사이클을 따른다는 점에 대해.  2 3 4 5 6 7 8

  4. Microsoft Learn, Differences between Windows PowerShell 5.1 and PowerShell 7.x. 실행 파일명이 powershell.exe에서 pwsh.exe로 바뀌어 사이드바이사이드를 뒷받침한다는 점, 첫 번째 위치 지정 매개변수가 -Command에서 -File로 바뀌었다는 점, PSWorkflow・PSScheduledJob・LocalAccounts 등의 모듈과 스냅인이 7에 포함되지 않는다는 점, Export-Csv의 #TYPE 기본 생략이나 Group-Object의 정렬된 출력 등의 동작 변경, 각 버전의 기반 .NET, 7.2 이후 MSI의 Microsoft Update 연계 옵션에 대해.  2 3 4 5 6 7 8 9 10 11

  5. Microsoft Learn, Migrating from Windows PowerShell 5.1 to PowerShell 7. PowerShell 7이 5.1과의 사이드바이사이드 공존을 전제로 설계되어 있다는 점(별도의 설치 경로・PSModulePath・프로필・이벤트 로그), 5.1의 설치 위치와 7의 설치 위치, 대부분의 기존 모듈이 7에서 동작하며 UseWindowsPowerShell로 호환성을 보완할 수 있다는 점, 삼항 연산자나 ForEach-Object -Parallel 등의 신기능, MSI/ZIP을 통한 배포에 대해.  2 3 4 5 6 7 8 9 10 11 12

  6. Microsoft Learn, about_Character_Encoding. Windows PowerShell 5.1의 기본 인코딩이 명령어(cmdlet)마다 일관되지 않는다는 점(Out-File과 리다이렉트는 UTF-16LE, Set-Content/Get-Content는 ANSI, Export-Csv는 ASCII 등), PowerShell 6 이후가 일률적으로 BOM 없는 UTF-8을 기본값으로 한다는 점, BOM 없는 스크립트를 5.1이 ANSI로 잘못 해석하기 때문에 비ASCII 문자를 포함한 스크립트는 BOM 포함 UTF-8로 저장해야 한다는 점, 코드 페이지 번호 지정이나 7.4의 ansi 값에 대해.  2 3 4 5 6 7 8 9 10 11

  7. Microsoft Learn, about_Windows_PowerShell_Compatibility. 호환 기능이 백그라운드의 Windows PowerShell 5.1 프로세스(WinPSCompatSession)에 모듈을 로드하고, 암묵적 원격 처리로 프록시 모듈을 생성하는 구조라는 점, UseWindowsPowerShell을 통한 명시적 로드와 자동 로드가 모두 있다는 점, 직렬화된 값으로 동작하며 원시 객체가 아니라는 점・로컬 Windows 한정・단일 런스페이스 공유・기본 로드 거부 목록이라는 제약에 대해.  2 3 4 5

  8. Microsoft Learn, about_Requires. #Requires 문이, 지정한 PowerShell 버전(-Version), 에디션(-PSEdition Core 또는 Desktop), 모듈 등의 전제 조건을 충족하지 않으면 스크립트의 실행 자체를 거부한다는 점에 대해.  2 3 4

  9. Microsoft Learn, about_Automatic_Variables. $PSVersionTable이 현재 세션의 PowerShell 버전 상세 정보를 보유하는 읽기 전용 해시 테이블이라는 점, PSEdition 속성이 5.1(전체 기능 버전 Windows)에서는 Desktop, 6 이후에서는 Core 값을 갖는다는 점에 대해.  2 3 4

  10. Microsoft Learn, PowerShell 7 module compatibility. Microsoft 제품의 각 모듈(Windows 관리 계열 모듈을 포함)의 PowerShell 7 대응 상황이 정리되어 있다는 점에 대해. 

  11. Microsoft Learn, Using Visual Studio Code for PowerShell Development. Windows PowerShell ISE가 Windows에 남지만 신기능 개발은 종료되었으며, PowerShell 5.1 이전에서만 동작한다는 점, Windows에서 삭제될 예정이 없으며 보안 및 우선순위가 높은 수정은 계속된다는 점, PowerShell 개발에는 Visual Studio Code와 PowerShell 확장 기능을 사용한다는 점, 세션 메뉴에서 사용할 PowerShell을 전환하거나 경로를 추가로 설정할 수 있다는 점, ISE의 조작감을 VS Code에서 재현하는 가이드가 마련되어 있다는 점에 대해.  2

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

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

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

자주 묻는 질문

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

Windows PowerShell 5.1과 PowerShell 7은 무엇이 다른가요?
별개의 제품입니다. 5.1은 Windows에 동봉되어 .NET Framework 위에서 동작하며, Microsoft는 신기능 추가를 종료했고 지원은 Windows 본체의 라이프사이클을 따릅니다. 7은 .NET(구 .NET Core) 위에서 동작하는 별도 설치 제품으로, 현재 개발의 중심축입니다. 7은 5.1을 대체하는 것이 아니라 별도 디렉터리에 설치되어 사이드바이사이드로 공존하며, 실행 파일명도 powershell.exe와 pwsh.exe로 구분됩니다.
PowerShell 7을 설치하면 기존의 5.1 스크립트는 망가지나요?
망가지지 않습니다. 7은 별도 디렉터리(기본값은 Program Files\PowerShell\7)에 설치되며, 모듈 저장 위치도 프로필도 5.1과 별도로 관리됩니다. 작업 스케줄러 등에서 powershell.exe를 실행하는 기존 구조는 지금까지처럼 5.1로 계속 동작합니다. 그렇기 때문에 반대로 '7을 설치하기만 해서는 아무것도 이행되지 않는다'는 점에 주의해야 하며, 7에서 동작시키고 싶은 스크립트는 실행 명령을 pwsh.exe로 명시적으로 전환해야 합니다.
PowerShell 7에서 지금까지의 스크립트가 문자 깨짐을 일으키는 이유는 무엇인가요?
기본 문자 인코딩이 바뀌었기 때문입니다. 5.1은 명령어(cmdlet)마다 기본값이 다르고(Out-File은 UTF-16LE, Get-Content는 ANSI 등), 7은 일률적으로 BOM 없는 UTF-8입니다. 일본어 환경에서는 Shift_JIS를 전제로 한 파일 연계가 많기 때문에, 기본값 그대로 이행하면 읽기와 쓰기 양쪽에서 깨질 수 있습니다. 파일 입출력의 -Encoding을 명시하는 것, 비ASCII 문자를 포함한 스크립트 자체를 BOM 포함 UTF-8로 저장하는 것, 이 두 가지로 거의 방지할 수 있습니다.
PowerShell 7에서 동작하지 않는 모듈은 어떻게 하면 되나요?
먼저 7에서 그대로 Import-Module하여 동작하는지 확인합니다. 동작하지 않는 경우, Windows 호환 기능(Import-Module -UseWindowsPowerShell)을 사용하면 백그라운드의 5.1 프로세스에 모듈을 로드하여, 원격 처리를 통해 7에서 사용할 수 있습니다. 다만 반환되는 것은 직렬화된 객체로 메서드를 호출할 수 없고, 로컬 Windows에서만 동작한다는 등의 제약이 있습니다. 이 제약에 걸리는 처리는 무리하지 말고 그 부분만 5.1인 채로 남기는 것이 현실적입니다.
사내 스크립트의 5.1에서 7로의 이행은 어떻게 진행하면 좋을까요?
일괄 전환이 아니라 단계적 이행으로 합니다. 먼저 작업 스케줄러와 스크립트 저장소에서 .ps1을 재고 조사하고, 각각을 7(pwsh)로 실행 테스트하여 동작하는지 확인합니다. 동작한 것부터 #Requires -Version 7을 추가하고, 작업 스케줄러의 실행 명령을 powershell.exe에서 pwsh.exe로 갱신합니다. 5.1에서만 동작하는 것은 무리하게 이행하지 않고, 어느 쪽에서 동작시켜야 하는지 명시한 뒤 남깁니다. 7 자체는 MSI나 winget으로 도입하고, 업데이트 배포 방법도 함께 정해 둡니다.

저자 프로필

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

Go Komura

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

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

블로그 목록으로 돌아가기