PowerShell 모듈 경로: 복사 및 붙여넣기 없이 재사용 가능한 코드

PowerShell 모듈을 사용하는 것은 PowerShell 자동화의 중요한 부분입니다. PowerShell을 배우기 시작할 때에는 일반적으로 단일 명령어를 사용하는 것으로 시작합니다. 이는 스크립트 작성으로 이어지고, 이는 함수 작성으로 이어집니다.

함수를 사용하면 스크립트를 보다 모듈화할 수 있습니다. 이를 통해 동일한 코드를 여러 곳에서 복사하고 붙여넣지 않고도 여러 장소에서 사용할 수 있습니다. 함수를 사용하면 동일한 코드가 사용된 모든 곳에서 동일한 편집을 하는 데 소요되는 시간을 더 적게 할 수 있습니다. 대신 하나의 장소에서 코드를 더 나은 형태로 개선할 수 있습니다.

함수를 다음 수준으로 가려면 이러한 함수를 모듈로 결합할 수 있습니다.

A module is a collection of functions in a text file with a psm1 extension. There are some optional additions, such as a module manifest and comment-based or external help that may also be included. These will be covered later on.

전제 조건

I’ll be using Windows PowerShell 5.1 in this article. If you’re using an older version or PowerShell Core, your mileage may vary as to results you see.

모듈과 상호 작용하기

PowerShell 세션을 처음 열면 두 개의 모듈이 시작됩니다. 첫 번째는 Microsoft.PowerShell.Utility로 이미 사용 중인 많은 기본 PowerShell 함수가 포함되어 있습니다. 다른 모듈은 PSReadline입니다. 이러한 시작 모듈을 Get-Module 명령을 사용하여 확인할 수 있습니다.

Listing modules with Get-Module

그러나 이는 사용 가능한 모든 모듈의 완전한 목록이 아닙니다. PowerShell 3부터 설치된 모듈은 필요한 경우에만 가져옵니다. 이전 버전의 PowerShell을 실행 중인 경우 명령을 사용하기 전에 모듈을 먼저 가져오기 위해 Import-Module 명령을 사용해야 합니다.

나중의 버전에서도 Import-Module을 사용하려는 경우도 있습니다. 이미 설치된 모듈을 가져오려면 다음과 같이 Import-Module을 사용할 수 있습니다:

Importing modules with Import-Module

Get-Module 명령은 가져온 모든 모듈을 표시하지만, 아직 가져오지 않은 모듈은 표시되지 않습니다. 그럴 때는 ListAvailable 매개변수를 사용하여 사용 가능한 다른 모든 모듈을 표시할 수 있습니다.

Listing all available modules with Get-Module -ListAvailable

기본적으로 모든 명령이 표시되지는 않습니다.

ExportedCommands 속성에는 모듈에서 내보낸 모든 사용 가능한 명령의 목록이 포함되어 있습니다. 이 목록과 모듈 파일에 있는 내용 사이에는 차이가 있을 수 있습니다. 내보낸 명령은 모듈 매니페스트에 내장된 기능으로, 작성자가 함수를 숨겨두는 데 사용할 수 있습니다. 모듈 작성자는 또한 Export-ModuleMember cmdlet을 사용할 수도 있지만, 이는 이 문서의 범위를 벗어납니다.

모듈 작성자는 함수를 숨길 수도 있는데, 이 경우 작성자는 매니페스트의 FunctionsToExport 배열에서 해당 함수를 제외시킵니다. 여기에서는 ExportedCommands 속성의 확장된 보기를 볼 수 있습니다.

Viewing exported commands

모듈 가져오기

모듈을 사용하기 위한 여러 가지 방법이 있습니다. 모듈 파일의 경로를 사용하여 수동으로 모듈을 가져올 수 있습니다. 이렇게 하면 모듈을 테스트하고 업데이트할 때 많은 작업을 하지 않아도 됩니다. 그러나 정확한 경로를 사용해야 하기 때문에 이동성이 많이 제한됩니다. 또한 PowerShell은 $env:PSModulePath 변수에 없는 모듈을 자동으로 가져오지 않습니다.

명령어 선택적으로 가져오기

Import-Module을 사용하여 Function 매개변수를 사용하여 모듈 전체가 아닌 특정 함수만 가져올 수 있습니다. 이는 Office 365 모듈과 같은 원격 시스템에서 모듈을 가져올 때 시간을 절약할 수 있습니다.

모든 사용자 모듈

모든 사용자에 대한 모듈은 C:\Program Files\WindowsPowerShell\Modules에 배치됩니다. 이 디렉토리에는 Install-Module을 사용하여 기본 범위 AllUsers를 사용하여 설치된 모든 모듈이 포함되어 있습니다.

현재 사용자 모듈

모듈을 설치하지만 특정 사용자만 사용하려는 경우 CurrentUser 범위가 있습니다. 이렇게 하면 모듈 파일이 문서 폴더의 C:\Users\<username>\Documents\WindowsPowerShell\Modules에 위치합니다. 이는 문서 폴더에 폴더 리디렉션을 사용하는 환경에서 유용할 수 있습니다.

이 경우 하나의 컴퓨터에 모듈을 설치하고 다른 컴퓨터에서 사용할 수 있습니다. 왜냐하면 두 컴퓨터가 동일한 문서 폴더를 공유하기 때문입니다.

시스템 모듈

완전성을 위해 C:\Windows\System32\WindowsPowerShell\1.0\Modules에도 모듈 디렉터리가 있습니다. 기술적으로는 이 경로에 배치된 모듈이 다른 경로 중 하나처럼 가져올 수 있지만, 이는 Microsoft의 시스템 모듈을 위해 예약된 경로이므로 권장되지 않습니다.

이름 짓기가 중요합니다

새 세션에서 기본적으로 사용할 수 있도록 모듈을 수동으로 이러한 경로 중 하나에 배치할 수 있지만, 모듈에 필요한 이름 짓기 규칙을 따라야 합니다. 모듈 파일이 위치한 폴더는 psm1 모듈 파일과 psd1 모듈 매니페스트(있는 경우)와 동일한 이름이어야 합니다.

우리가 이전에 언급한 것처럼 Get-Module -ListAvailable을 사용하면 이러한 경로를 참조합니다. $env:PSModulePath -Split ';'를 사용하여 모든 모듈 경로를 볼 수 있습니다. 여기에 표시된 것과 다른 경로가 목록에 표시될 수도 있습니다. 많은 프로그램은 설치될 때 자체 모듈 경로를 추가합니다. 이 중 하나의 예로 SQL이 있으며, 별도의 모듈 경로에 포함된 자체 모듈을 가지고 있습니다.

Viewing module paths with $env:PSModulePath

다른 프로세스를 통해 설치해야 하는 모듈도 있습니다. 가장 중요한 예 중 하나는 ActiveDirectory 모듈입니다. Windows 7부터 Windows 10 1803까지는 원격 서버 관리 도구(RSAT) 설치 프로그램을 사용하여이 모듈을 설치해야 합니다.

Windows 10의 최신 버전(1809+)에서는 기능 요청에 따른 기능을 통해서만 사용할 수 있습니다. RSAT를 설치하면 ActiveDirectory 모듈과 다른 Windows 역할을 관리하는 데 사용되는 많은 모듈이 함께 설치됩니다. Windows Server 운영 체제에서는 이러한 모듈을 Server Manager를 통해 설치합니다.

원격 모듈 가져오기 (암시적 원격)

로컬에서 모듈을 실행하는 것이 현실적이지 않은 경우가 있습니다. 대신 원격 장치에 연결하여 설치된 모듈을 가져오는 것이 더 좋습니다. 이렇게 하면 명령이 실제로 원격 컴퓨터에서 실행됩니다. 이는 Microsoft의 Office 365 모듈과 자주 사용됩니다. 이들 중 많은 모듈은 Office 365 서버에 연결하여 모듈을 가져옵니다. 명령 중 하나를 실행하면 원격 서버에서 실행되고 출력이 세션으로 다시 전송됩니다.

원격 모듈을 가져오는 또 다른 사용 사례는 로컬에 모듈이 설치되어 있지 않은 경우입니다. 이는 ActiveDirectory 모듈이 설치되어 있지 않지만 가져오려고 할 때 발생합니다.

Module not installed

원격 모듈을 가져오려면 먼저 PSSession을 생성해야 합니다. New-PSSession을 사용하여 세션을 생성할 수 있습니다. 그런 다음 Import-ModulePSSession 매개변수를 사용하여 원격 장치에 있는 모듈을 가져올 수 있습니다.

PS51> $AdminServer = New-PSSession -ComputerName $AdminServerName -Credential (Get-Credential)
PS51> Import-Module -Name ActiveDirectory -PSSession $AdminServer -Prefix 'Rmt'

원격 모듈을 가져오는 이 방법은 분산 환경에서 더 빠른 코드 실행을 가능하게 합니다. 예를 들어, 컴퓨터에서 작업하고 있는데 작업 중인 서버가 미국 전역에 분산되어 있다면 로컬에서 서버에 대해 일부 명령을 실행하는 데 상당한 시간이 소요될 수 있습니다. 그러나 명령을 서버에서 실행하고 출력을 로컬 세션으로 전달하는 것은 훨씬 빠릅니다.

모듈 접두사 추가

원격 컴퓨터에서 가져온 함수에도 접두사를 추가할 수 있습니다. 이 옵션은 로컬 모듈을 가져올 때 사용할 수 있지만, 모듈의 다른 버전을 테스트하는 경우를 제외하면 거의 사용되지 않습니다.

위의 가져오기 명령을 실행하면 다음과 같은 결과가 표시됩니다:

Viewing all available commands in a module

이 경우에는 접두사를 사용하여 이것이 로컬 모듈이 아님을 나타낼 수 있습니다. 이는 로컬에서도 사용 가능한 모듈을 가져올 때 사용할 수 있습니다. 접두사를 추가하면 코드가 실행되는 위치에 대한 혼동을 줄일 수 있습니다.

모듈 제거

Remove-Module을 사용하지 않고도 현재 세션에서 모듈을 제거할 수 있습니다. 이렇게 하면 모듈 파일을 제거하지 않고 현재 세션에서 모듈이 제거됩니다. 모듈을 사용하기 위해 원격 세션을 사용하고 있던 경우에는 이를 사용할 수 있습니다. Remove-Module을 사용하여 세션을 정리한 다음 원격 세션을 연결을 끊을 수 있습니다.

Removing a module from the session

Remove-Module의 또 다른 사용 방법은 모듈을 변경하고 새로운 PowerShell 세션을 시작하지 않으려는 경우입니다. 이 경우에는 Remove-Module 다음에 Import-Module을 사용하여 모듈을 다시로드합니다. 또는 Import-Module과 함께 Force 매개변수를 사용할 수도 있습니다. 이렇게 하면 모듈이 제거되고 다시 로드됩니다.

PowerShell 모듈의 구성 요소

A module can consist of one or more files. To meet the minimum requirements for a module, you must have a module file. This can be a PSM1 file or any other module file such as a binary module file. To build upon that, your psm1 should have functions defined in it, or it will not be much use to anyone.

함수의 모양이나 수행하는 작업에 대한 요구사항은 없지만 몇 가지 지침이 있습니다. 일반적으로 모든 함수를 동일한 개념을 기반으로 하는 모듈에 포함하는 것이 선호됩니다.

모듈에는 관련된 함수가 포함되어야 합니다.

예를 들어, ActiveDirectory 모듈은 Active Directory와 상호작용하는 함수만 포함합니다. 일반적으로 함수 이름에는 접두사가 포함됩니다. ActiveDirectory 모듈을 다시 예로 들면, 함수 이름의 명사는 모두 AD로 시작합니다.

이러한 지침을 사용하면 함수를 쉽게 찾을 수 있습니다. 새로운 모듈을 가져와서 함수를 탭 키로 탐색하려는 경우, 함수의 이름 구조가 유사하다면 이 작업이 훨씬 쉬워집니다. 모듈 이름이 PS로 시작하는 경우가 많지만, 이 접두사는 공식적으로 Microsoft 모듈에만 사용 가능합니다. 모듈의 시작 부분에 PS를 사용해도 문제가 발생하지는 않을 것입니다만, 다른 모듈 이름과 충돌을 일으킬 수 있습니다.

이러한 지침을 사용하여 레지스트리와 상호작용하는 여러 함수가 있는 경우 다음과 같은 형식으로 작성할 수 있습니다:

function Get-ATARegistryKey {...}

function Set-ATARegistryKey {...}

모듈 매니페스트

텍스트 모듈 파일을 보완하기 위해 모듈 매니페스트를 포함할 수도 있습니다. 이 파일은 PSD1 확장자를 가지며 모듈에 대한 메타데이터를 포함합니다. 여기에는 작성자 정보, 모듈 설명, 필요한 다른 모듈 및 기타 속성에 대한 정보를 포함할 수 있습니다. 저장소에 게시하려면 AuthorDescription 필드를 작성해야 합니다.

다음은 등록 모듈에 대한 매니페스트 예시입니다:

#ATARegistry 모듈에 대한 모듈 매니페스트
#작성자: Tyler
#작성일: 2019년 8월 11일
@{
	#이 매니페스트와 연관된 스크립트 모듈 또는 이진 모듈 파일입니다.
	RootModule = 'ATARegistry'
	#이 모듈의 버전 번호입니다.
	ModuleVersion = '1.0'
	#지원되는 PSEditions
	#CompatiblePSEditions = @()
	#이 모듈을 고유하게 식별하는 데 사용되는 ID입니다.
	GUID = 'fef619fa-016d-4b11-a09d-b222e094de3e'
	#이 모듈의 작성자입니다.
	Author = 'Tyler Muir'
	#이 모듈의 회사 또는 공급업체입니다.
	CompanyName = 'Adam the Automator'
	#이 모듈의 저작권 표시입니다.
	Copyright = '(c) 2019 tyler. All rights reserved.'
	#이 모듈이 제공하는 기능에 대한 설명입니다.
	Description = 'This is a test module.'
	#이 모듈에 필요한 최소 Windows PowerShell 엔진 버전입니다.
	#PowerShellVersion = ''
	#이 모듈에 필요한 Windows PowerShell 호스트의 이름입니다.
	#PowerShellHostName = ''
	#이 모듈에 필요한 최소 Windows PowerShell 호스트 버전입니다.
	#PowerShellHostVersion = ''
	#이 모듈에 필요한 최소 Microsoft .NET Framework 버전입니다. 이 전제 조건은 PowerShell Desktop 버전에만 적용됩니다.
	#DotNetFrameworkVersion = ''
	#이 모듈에 필요한 최소 공용 언어 런타임 (CLR) 버전입니다. 이 전제 조건은 PowerShell Desktop 버전에만 적용됩니다.
	#CLRVersion = ''
	#이 모듈에 필요한 프로세서 아키텍처 (None, X86, Amd64)입니다.
	#ProcessorArchitecture = ''
	#이 모듈을 가져오기 전에 전역 환경에 가져와야 하는 모듈입니다.
	#RequiredModules = @()
	#이 모듈을 가져오기 전에 로드해야 하는 어셈블리입니다.
	#RequiredAssemblies = @()
	#이 모듈을 가져오기 전에 호출자의 환경에서 실행되는 스크립트 파일(.ps1)입니다.
	#ScriptsToProcess = @()
	#이 모듈을 가져올 때 로드할 유형 파일(.ps1xml)입니다.
	#TypesToProcess = @()
	#이 모듈을 가져올 때 로드할 형식 파일(.ps1xml)입니다.
	#FormatsToProcess = @()
	#RootModule/ModuleToProcess에 지정된 모듈의 중첩 모듈로 가져올 모듈입니다.
	#NestedModules = @()
	#이 모듈에서 내보낼 함수입니다. 성능을 위해 와일드카드를 사용하지 않고 삭제하지 마세요. 함수가 없는 경우 빈 배열을 사용하세요.
	FunctionsToExport = @('Get-RegistryKey','Set-RegistryKey')
	#이 모듈에서 내보낼 cmdlet입니다. 성능을 위해 와일드카드를 사용하지 않고 삭제하지 마세요. cmdlet이 없는 경우 빈 배열을 사용하세요.
	CmdletsToExport = @()
	#이 모듈에서 내보낼 변수입니다. VariablesToExport = '*'를 사용하세요.
	#이 모듈에서 내보낼 별칭입니다. 성능을 위해 와일드카드를 사용하지 않고 삭제하지 마세요. 별칭이 없는 경우 빈 배열을 사용하세요.
	AliasesToExport = @()
	#이 모듈에서 내보낼 DSC 리소스입니다.
	#DscResourcesToExport = @()
	#이 모듈과 함께 패키지화된 모든 모듈의 목록입니다.
	#ModuleList = @()
	#이 모듈과 함께 패키지화된 모든 파일의 목록입니다.
	#FileList = @()
	#RootModule/ModuleToProcess에 지정된 모듈에 전달할 개인 데이터입니다. 이 데이터에는 PowerShell에서 사용되는 추가 모듈 메타데이터를 포함할 수도 있습니다.
	PrivateData = @{
		PSData = @{
			#이 모듈에 적용된 태그입니다. 온라인 갤러리에서 모듈 검색을 돕습니다.
			#Tags = @()
			#이 모듈의 라이선스에 대한 URL입니다.
			#LicenseUri = ''
			#이 프로젝트의 주요 웹사이트에 대한 URL입니다.
			#ProjectUri = ''
			#이 모듈을 나타내는 아이콘에 대한 URL입니다.
			#IconUri = ''
			#이 모듈의 릴리스 노트입니다.
			#ReleaseNotes = ''
		} 
		#PSData 해시 테이블의 끝입니다.
	} 
	#PrivateData 해시 테이블의 끝입니다.
	#이 모듈의 HelpInfo URI입니다.
	#HelpInfoURI = ''
	#이 모듈에서 내보낸 명령에 대한 기본 접두사입니다. Import-Module -Prefix를 사용하여 기본 접두사를 재정의할 수 있습니다.
	#DefaultCommandPrefix = ''
}

처음에는 이것이 무섭게 보일 수 있지만, Microsoft는 모듈 매니페스트를 생성하는 데 사용할 수 있는 편리한 cmdlet을 제공합니다. 포함된 명령은 New-ModuleManifest입니다. 위에 표시된 매니페스트를 생성하기 위해 다음을 사용할 수 있습니다:

PS51> New-ModuleManifest -Path .\Scripts\TestModule.psd1 -Author 'Tyler Muir' -CompanyName 'Adam the Automator' -RootModule 'TestModule.psm1' -FunctionsToExport @('Get-RegistryKey','Set-RegistryKey') -Description 'This is a test module.'

외부 도움말 파일

몇몇 모듈에서는 외부 도움말 파일을 볼 수도 있습니다. 파일 이름 끝에 <ModuleName>-Help.xml이 포함되어 있을 수 있습니다. 이러한 외부 도움말 파일에는 일반적으로 함수 정의에서 찾을 수 있는 명령 기반 도움말에 포함되는 동일한 정보가 포함되어 있습니다.

이를 위해서는 모듈을 가져온 후 Get-Help 명령을 사용할 때 함수에 # .ExternalHelp <ModulePath>-Help.xml를 추가해야 합니다. 대개 매우 큰 모듈에 외부 도움말 파일이 있는 것이 일반적이며, 그로 인해 이는 범위를 벗어납니다.

이러한 파일은 모듈에서 볼 수 있는 가장 일반적인 파일 유형이지만, 유일한 파일은 아닙니다. 때로는 텍스트 모듈 외에도 이진 파일을 볼 수도 있으며, 다른 종속성이 있을 수 있습니다. 모듈 경로를 통해 추가 파일 유형에 대한 여러 예제를 찾을 수 있습니다.

비표준 모듈 파일을 올바르게 게시하려면 모듈 매니페스트의 FileList 매개변수에 다른 파일을 포함해야 합니다.

모듈 매니페스트 내에서 현재 비어있는 매개변수들을 확인할 수 있습니다. 이러한 매개변수들을 사용하여 모듈 사용에 대한 다른 요구사항을 정의할 수 있습니다. 예를 들어, 모듈이 작동할 수 있는 PowerShell 버전을 정의할 수 있습니다. 지원되지 않는 PowerShell 버전에서 모듈을 가져오려고 할 때 다음과 같은 메시지가 표시됩니다:

Requiring certain versions of PowerShell

PSRepositories

모듈의 주요 배포 옵션 중 하나는 PSRepository입니다. PSRepository는 여러 사람 또는 여러 장치에서 모듈 파일에 액세스할 수 있는 로컬입니다. 이는 파일을 게시할 수 있는 웹 서버인 경우가 많습니다.

리포지토리로 디렉토리를 사용할 수도 있지만, 이는 리포지토리의 기능을 제한합니다. PSRepository를 직접 호스팅하거나 PowerShell 갤러리와 같은 인터넷에서 제공되는 다양한 옵션 중 하나를 활용할 수 있습니다. Get-PSRepository 명령을 사용하여 PSRepositories를 확인할 수 있습니다.

Default PowerShell NuGet repositories

기본적으로 하나의 항목만 있으며 PowerShell 갤러리에 대한 항목입니다. 신뢰되지 않음이라고 표시될 수 있습니다. 이는 PowerShell 갤러리를 사용할 경우 Microsoft에서 승인하지 않은 코드를 사용할 수 있음을 알려주기 위한 것입니다. 따라서 모듈이 설치되기 전에 명시적인 허가를 부여해야 합니다.

PSRepositories 추가

자체 리포지토리를 추가할 수도 있습니다. PowerShell 갤러리를 신뢰하기 위해 Get-PSRepository -Name PSGallery | Set-PSRepository -InstallationPolicy Trusted를 실행하거나 PowerShell 갤러리에서 모듈을 처음 설치할 때 경고를 수락할 수 있습니다.

이러한 PSRepositories와 상호 작용할 때 사용하는 모든 명령은 PowerShellGet 모듈에서 찾을 수 있습니다. 함수는 다음에서 확인할 수 있습니다:

Commands in the PowerShellGet module

특정 저장소와 상호 작용하기 전에 PowerShellGet 모듈을 업데이트해야 할 수도 있습니다.

모듈 찾기

PSRepository를 사용하는 또 다른 주요 기능은 모듈을 검색할 수 있는 기능입니다. 이는 Find-Module 명령을 사용하여 수행할 수 있습니다. 여러 가지 필터링 방법이 있지만, 지금은 VMware 모듈을 검색하는 방법을 알아보겠습니다:

Finding modules on the PowerShell Gallery

이렇게 하면 VMware로 시작하는 모든 모듈이 표시됩니다. 이 중 대부분은 VMware에서 제공한 것입니다. 그러나 모듈을 게시한 작성자를 확인하려면 작성자 속성을 살펴봐야 합니다.

PowerShell 갤러리에는 누구나 업로드할 수 있기 때문에 수천 개의 모듈을 사용할 수 있습니다. 따라서 사용 사례에 맞지 않게 작동하는 모듈을 발견할 수도 있습니다. 대부분의 모듈은 오픈 소스이므로 모듈의 기능을 개선하기 위해 기여할 수 있습니다.

모듈 설치

Install-Module 명령을 사용하려면 모듈을 호스팅하는 신뢰할 수 있는 PSRepository가 있어야 합니다. 이는 PowerShell 갤러리, 다른 인터넷 PSRepository 또는 자체 호스팅 사이트일 수 있습니다. 모듈을 설치하기 전에 Find-Module 명령에서 파이프하여 모듈을 쉽게 확인할 수 있습니다.

Finding modules installed from a PSRepository

MinimumVersion, MaximumVersion, 또는 RequiredVersion 매개변수를 사용하여 모듈의 버전을 정의할 수도 있습니다.

Install-Module를 사용하여 설치된 모든 모듈을 보려면 Get-InstalledModule을 사용할 수 있습니다. 이 명령은 AllUsers 범위나 CurrentUser 범위에 설치된 모든 모듈을 나열합니다.

모듈 제거

모듈을 설치할 수 있는 것처럼 모듈을 제거할 수도 있습니다. 모듈이 Install-Module 명령을 통해 설치되지 않았다면 Uninstall-Module 명령으로 제거할 수 없습니다.

Uninstalling modules installed from a PSRepository with Uninstall-Module

여기에서는 ActiveDirectory 모듈을 제거하려고 시도하는 것을 볼 수 있습니다. 이 모듈이 Install-Module을 사용하여 설치되지 않았으므로 Uninstall-Module을 사용하려고 하면 오류가 발생합니다. 이 모듈을 제거하려면 모듈을 설치할 때 사용한 것을 반대로 제거해야 합니다.

모듈을 성공적으로 제거하려면 이전에 설치한 VMware.PowerCLI 모듈을 제거할 수 있습니다.

Uninstalling a module downloaded from the PowerShell Gallery

VMware.PowerCLI를 제거했음에도 불구하고 여전히 많은 종속성이 설치되어 있는 것을 볼 수 있습니다. 모든 모듈을 제거하려면 Get-InstalledModule VMware.* | Uninstall-Module -Force를 사용할 수 있습니다.

이 모듈을 완전히 제거하는 데 어려움이 있는 이유는 종속성이 많기 때문입니다. 게다가 일부 모듈은 서로의 종속성입니다. 이러한 이유로 Force 매개변수가 필요합니다.

모듈 업데이트

이제 모듈을 설치하고 제거하는 방법을 알았으니, 설치한 모듈을 어떻게 업데이트하는지 궁금할 것입니다.

다른 프로세스와 마찬가지로, 모듈이 Install-Module을 사용하여 설치되지 않았다면 PowerShell 명령을 사용하여 업데이트할 수 없습니다. Update-Module을 사용하여 모듈을 최신 릴리스로 업데이트하거나 더 높은 특정 버전으로 업데이트할 수 있습니다.

또한, AllowPreRelease 스위치를 사용하여 공식적으로 릴리스되지 않은 버전으로 업데이트할 수도 있습니다. 때때로 이것은 체험 중인 버그에 대한 수정이나 사용하려는 새로운 기능과 같이 도움이 될 수 있습니다.

Updating modules with Update-Module

모듈 검사/저장

사용하기 전에 모듈을 검사하는 데 매우 유용한 하나의 덜 사용되는 명령은 Save-Module입니다. 이 명령을 사용하여 모듈을 설치하지 않고 특정 경로로 다운로드할 수 있습니다.

그런 다음 파일을 검사하고 모듈이 바이너리 모듈이 아닌 경우 모듈을 구성하는 코드를 열어볼 수 있습니다. 이는 모듈이 악성 행위를 하지 않는지 확인하는데만 유용한 것뿐만 아니라, 다른 사람들이 모듈을 어떻게 구성하는지 배우는 데에도 도움이 될 수 있습니다.

Downloading modules with Save-Module

이 예제에서는 VMware.PowerCLI 모듈뿐만 아니라 해당 모듈에 대한 모든 종속성도 다운로드됩니다. VMware.PowerCLI 폴더에는 다음과 같은 내용이 표시됩니다:

VMware.PowerCLI module contents

이는 종종 최종 사용자 라이선스 동의서와 같은 표준이 아닌 모듈 파일도 모듈에 포함되어 있는 경우가 있는 좋은 예입니다.

자체 모듈 작성

이제 다른 사람의 모듈과 상호 작용하는 방법을 보았습니다. 이제 코드 확장성을 위해 자체 모듈을 생성하는 방법을 배우고 싶습니다.

템플릿 파일 생성

먼저 모든 모듈 파일을 위한 폴더를 생성해야 합니다. 컨테이너를 생성한 후 모듈 파일을 만들어야 합니다. 모듈 파일의 이름은 폴더와 동일하게 지정해야 하며, 그렇지 않으면 모듈을 게시할 때 PowerShell이 모듈을 올바르게 찾지 못할 수 있습니다.

PS51> New-Item -Path .\Scripts -Name ATARegistry -ItemType Directory
PS51> New-Item -Path .\Scripts\ATARegistry -Name ATARegistry.psm1

이제 매니페스트를 사용하고 싶다면, 컨테이너와 모듈 파일과 동일한 이름을 지정해야 합니다.

PS51> New-ModuleManifest -Path .\Scripts\ATARegistry\ATARegistry.psd1 -Author 'Tyler Muir' -CompanyName 'Adam the Automator' -RootModule ATARegistry.psm1 -Description 'Used for interacting with registry keys'

컨테이너, 모듈 파일 및 매니페스트 파일이 있으면 완전한 기능을 갖춘 모듈이 생성됩니다. 이 모듈을 PSRepository에 게시하고 원하는 곳에 설치할 수 있습니다. 그러나 모듈 파일이 비어 있기 때문에 큰 도움이 되지 않을 수 있습니다. 여전히 이러한 파일을 사용하여 리포지토리가 작동하는지 테스트할 수 있습니다.

PSRepository 등록

모듈을 게시하기 전에 세션에 다른 PSRepository를 추가해야 합니다. 테스트를 위해 PSRepository로 로컬 경로를 사용할 수 있으며, 설정 및 해제가 쉽습니다.

일반적으로 디렉토리로 PSRepository를 설정할 경우 여러 컴퓨터에서 액세스할 수 있도록 해야 합니다. 다음과 같이 로컬 리포지토리를 생성할 수 있습니다:

PS51> New-Item -Path C:\ -Name Repo -ItemType Directory
PS51> Register-PSRepository -Name 'LocalRepo' -SourceLocation 'C:\Repo' -PublishLocation 'C:\Repo' -InstallationPolicy Trusted

PSRepository에서만 다운로드하고 게시하지 않는 경우 PublishLocation 매개변수를 제외할 수 있습니다.

모듈 게시

신뢰할 수 있는 설치 정책을 설정했기 때문에 저장소에서 모듈을 설치하려는 경우 확인을 받지 않게 됩니다. 이제 새로운 PSRepository를 사용할 수 있으므로 Publish-Module -Name .\Scripts\ATARegistry -Repository LocalRepo를 사용하여 모듈을 게시할 수 있습니다.

모듈을 게시한 후에는 위의 명령을 사용하여 모듈을 찾고 설치할 수 있습니다.

모듈을 설치한 후에는 Get-Module을 사용하여 모듈이 로컬 세션에 가져와졌는지 확인할 수 있습니다. Manifest 파일의 FunctionsToExport 배열에 함수를 추가하지 않았으므로 ExportedCommands 속성은 비어 있습니다.

No exported commands

모듈에 추가하기

이제 모듈을 게시하고 설치할 수 있다는 것을 알았으므로 기능을 추가해볼 수 있습니다. 레지스트리 키를 반환하는 함수를 추가할 수 있습니다. 예를 들면 다음과 같습니다:

function Get-ATARegistryKey {
    param (
        [string]$Path
    )
    Get-Item $Path
}

Manifest를 그대로 두고 새 모듈을 업로드하려고 하면 두 가지 문제가 발생합니다. 첫 번째 문제는 Manifest 파일에서 모듈 버전을 변경하지 않았기 때문에 모듈의 버전이 이미 저장소에 존재한다는 오류가 발생한다는 것입니다.

모듈 함수 내보내기

다른 문제는 모듈을 가져온 후에도 ExportedCommands 속성에 함수가 표시되지 않는다는 것입니다. 이는 새 함수를 Manifest에 추가하지 않았기 때문입니다.

함수를 FunctionsToExport 목록에 나열하지 않고도 사용할 수 있지만, 이렇게 하면 찾기가 어려워집니다.

빈 배열을 정의하지 않는 한, @()을 사용하여 FunctionsToExport에 대한 모든 함수, 변수 및 별칭이 기본적으로 내보내집니다.

이러한 두 가지 문제를 해결하기 위해 모듈 파일을 다음과 같이 업데이트할 수 있습니다:

ModuleVersion = '1.1'
FunctionsToExport = 'Get-RegistryKey'

이제 함수를 모듈에 추가하고 매니페스트를 이러한 변경 사항을 반영하도록 업데이트했으므로 이전과 동일한 명령을 사용하여 모듈의 새 버전을 게시할 수 있습니다.

PS51> Publish-Module -Name .\Scripts\ATARegistry -Repository LocalRepo.

함수 내보내기 및 Export-ModuleMember 사이의 선택

PowerShell에서 모듈 멤버를 내보낼 때 두 가지 유사한 기능이 있습니다. 문제는 둘 사이에서 선택하는 것입니다. 두 가지 모두 올바르지만, 필요에 따라 어느 것이 더 잘 작동할지는 달라질 수 있습니다.

함수를 동적으로 제어하려면 내보내려는 함수 목록을 전달할 수 있는 Export-ModuleMember를 사용하십시오. 일반적으로 이는 여러 개별 함수 PS1 파일을 도트 소스로 사용할 때 사용됩니다. 내부 함수를 비공개 폴더로 분할하고 내보낼 함수를 공개 폴더로 분할하여 모든 공개 함수를 Export-ModuleMember 함수에 전달하여 쉽게 내보낼 수 있습니다.

A few notes about Export-ModuleMember:

  • FunctionsToExport의 동작을 무시하며, Export-ModuleMember 명령이 사용되면 FunctionsToExport에는 영향을 미치지 않습니다.
  • Export-ModuleMember는 명시적으로 정의하지 않은 변수와 별칭을 내보내지 않습니다. 반면, FunctionsToExport는 해당 값을 내보냅니다.
  • 여러 개의 Export-ModuleMember 명령을 사용할 수 있으며, 이는 우선순위가 아닌 스택으로 쌓입니다.

함수 목록에 변경이 예상되지 않는 경우 모듈 매니페스트의 FunctionsToExport 구성을 사용하면 문제없이 작동하며 변수와 별칭을 명시적으로 내보내지 않아도 됩니다.

모듈 업데이트

마지막 단계는 세션에서 모듈을 업데이트하여 업데이트된 파일을 사용할 수 있게하는 것입니다. Update-Module ATARegistry를 사용하여 방금 리포지토리에 게시한 업데이트를 다운로드합니다.

Exported commands now show up

이제 새 버전의 모듈이 있고 매니페스트에 정의한 함수를 볼 수 있습니다.

도움말 콘텐츠 작성

이전에 넘어간 옵션 중 하나는 PowerShell에 내장된 도움말 시스템입니다. 어떤 함수에 대해 Get-Help를 사용한 적이 있을 것입니다. 이 정보는 주로 두 가지 주요 방법을 사용하여 추가할 수 있습니다.

첫 번째 방법은 함수 정의에 주석 기반 도움말을 추가하는 것입니다. 이는 많은 모듈 작성자가 일반적으로 사용하는 방법입니다. 다른 방법은 외부 도움말 파일을 사용하는 것입니다. Full 매개변수를 사용하여 도움말이 제공하는 모든 내용을 표시할 수 있습니다.

Finding help with Get-Help

보시다시피 정보가 많지 않으며, 얻는 작은 정보도 아무에게도 도움이 되지 않을 가능성이 큽니다.

모듈 파일에 주석 기반 도움말을 추가하여 도움말 시스템의 이러한 필드를 채울 수 있습니다. Get-Help about_Comment_Based_Help를 사용하여 주석 기반 도움말에 대한 모든 옵션에 대해 읽어볼 수 있습니다.

지금은 함수를 다음과 같이 업데이트할 수 있습니다. 이는 가장 일반적으로 사용되는 도움말 매개변수 목록입니다. 하지만 이들은 여전히 선택적이며 대신 추가할 수 있는 다른 매개변수도 있습니다.

이제 함수는 다음과 같이 보입니다:

 function Get-RegistryKey {
	<#
	    .SYNOPSIS
	    지정된 경로를 사용하여 레지스트리 키를 반환합니다.
	    .DESCRIPTION
	    이 함수는 Get-Item 명령을 사용하여 지정된 레지스트리 키에 대한 정보를 반환합니다.
	    .PARAMETER Path
	    레지스트리 키를 검색할 경로입니다.
	    .EXAMPLE
	    Get-RegistryKey -Path 'HKLM:\HARDWARE\DESCRIPTION\System'
	    .INPUTS
	    System.String
	    .OUTPUTS
	    Microsoft.Win32.RegistryKey
	    .NOTES
	    이 모듈은 잘 문서화된 함수의 예입니다.
	    .LINK
	
ATA Learning
#>
param( [string]$Path ) Get-Item $Path }

.FORWARDHELPTARGETNAME과 같은 특수 도움말 매개변수가 있습니다. 이 옵션은 모든 들어오는 도움말 요청을 다른 명령으로 전달합니다. 이는 도움말이 여러 명령에 대해 동일한 정보를 표시해야 할 경우에 사용될 수 있습니다.

이제 도움말을 추가했으므로 모듈 매니페스트에서 버전을 업데이트하고 새 버전을 게시하고 이전에 수행한 것과 같이 설치된 버전을 업데이트할 수 있습니다.

이제 함수의 도움말을 확인하면 더 많은 정보를 확인할 수 있습니다. 이는 코드를 살펴보는 것만으로는 모듈이 무엇을 하는지 빠르게 이해하기 어려울 수 있는 경험이 적고 덜 경험이 있는 사용자에게 함수 사용 방법에 대한 문서를 포함하는 좋은 방법입니다.

Getting full help content with Get-Help

외부 도움 파일의 경우, 추가된 정보는 동일하지만 정보는 별도의 파일에 배치되고 함수 내에서 링크됩니다.

모듈 경로 AllUsers를 확인하면 모듈의 버전과 설치한 모든 모듈 파일을 볼 수 있습니다.

Folder name is the module version

이전에 만든 PSRepository 경로 C:\Repo로 돌아가면 여러 NUPKG 파일을 볼 수 있습니다. 각 버전에 대해 하나씩 있을 것입니다. 이는 Publish-Module을 사용하여 게시할 때 게시한 것의 압축 버전입니다.

요약

PowerShell 콘솔, PowerShell 언어 및 스크립트 작성에 대해 이해한 후, 자체 모듈을 작성하는 것이 마지막 단계입니다. 모듈을 사용하면 PowerShell에서 유용한 도구를 개발할 수 있습니다. 모듈을 단일 목적으로 만들어 올바르게 설계하고 작성하면 시간이 지남에 따라 점차적으로 더 적은 코드를 작성하게 될 것입니다. 모듈 기능을 더 많은 코드에서 참조하고 거기서부터 작성하기 시작할 것입니다.

모듈 기능을 사용하면 스크립트에서 반복되는 코드를 추상화할 수 있습니다. 이는 나중에 호출할 수 있는 “레이블”로서 코드에서 나중에 참조하는 것을 나타내며, 이미 이전에 목표를 달성하는 방법을 알아냈기 때문에 바퀴를 다시 발명하고 과거에 이미 해결한 문제에 대해 이해하려고 애를 쓰는 것을 방지합니다. 모듈은 PowerShell 코드를 “패키지”로 묶어서 이미 해결한 문제에 시간을 낭비하지 않도록 관련 코드를 그룹화하는 것입니다.

Source:
https://adamtheautomator.com/powershell-modules/