将 Azure Artifacts 源用作专用 PowerShell 存储库
Azure DevOps Services
Azure Artifacts 提供了一个方便的解决方案,用于共享 PowerShell 脚本。 通过使用 Azure Artifacts 源,可以从命令行无缝发布 PowerShell 模块,并通过源设置控制对这些模块的访问。 本文将指导你设置 Azure Artifacts 源作为专用 PowerShell 存储库来存储和共享 PowerShell 模块。
本文将指导如何进行以下操作:
- 创建个人访问令牌
- 创建 PowerShell 模块
- 创建 SecretStore 保管库并注册存储库
- 从源发布和使用包
先决条件
安装 PSResourceGet。
注意
PSResourceGet 不支持 Azure Artifacts 凭据提供程序。
创建个人访问令牌
个人访问令牌充当数字标识,充当使用 Azure DevOps 进行身份验证的替代密码。
导航到 Azure DevOps 组织
https://dev.azure.com/<ORGANIZATION_NAME>/
选择用户设置图标,选择 “个人访问令牌”,然后选择“ 新建令牌”。
输入 PAT 的名称,设置到期日期,选择“自定义”,然后选择“打包>读取”、“写入和管理”。
完成后选择“创建”,并确保将 PAT 复制并存储在安全的位置。
创建 PowerShell 模块
如果没有自己的模块,请按照本节中的说明创建示例 PowerShell 模块。 否则,请跳到下一步:
创建新的文件夹 PowerShell-Demo。 导航到文件夹并创建新文件 PowerShell-Demo.psm1。
将以下脚本粘贴到 PowerShell-Demo.psm1 文件中:
Function PowerShell-Demo{ Write-Host "Hello World!" }
通过在 PowerShell-Demo 目录中运行以下命令生成模块清单:
New-ModuleManifest -Path .\PowerShell-Demo.psd1
打开 PowerShell-Demo.psd1 文件并找到变量
RootModule
。 此设置指定导入模块时 PowerShell 加载的主脚本文件。 将空字符串替换为 PowerShell-Demo.psm1 文件的路径:RootModule = 'PowerShell-Demo.psm1'
本
FunctionsToExport
部分指定导入模块时用户可以访问哪些函数。 包括 PowerShell-Demo 函数:FunctionsToExport = @('PowerShell-Demo')
找到该
FileList
部分,其中列出了打包模块时包含的文件。 使用模块添加要打包的文件:FileList = @('./PowerShell-Demo.psm1')
注册存储库
运行以下命令以创建凭据对象。 将占位符替换为正确的信息。
$username = "<USER_NAME>" $patToken = "<PERSONAL_ACCESS_TOKEN>" | ConvertTo-SecureString -AsPlainText -Force $credentials = New-Object System.Management.Automation.PSCredential($username, $patToken)
确保 已安装 SecretManagement 和 SecretStore ,然后运行以下命令来创建保管库并添加机密:
Register-SecretVault -Name "MySecretVault" -ModuleName Microsoft.PowerShell.SecretStore -DefaultVault Set-Secret -Name "MyCredential" -Secret $credentials -Vault "MySecretVault" $CredentialInfo = [Microsoft.PowerShell.PSResourceGet.UtilClasses.PSCredentialInfo]::new('MySecretVault', 'MyCredential')
若要验证保管库和机密是否已成功创建,请运行以下命令列出所有机密:
PS > Get-SecretInfo Name Type VaultName ---- ---- --------- MyCredential PSCredential MySecretVault
运行以下命令来注册 PowerShell 存储库。 可以通过导航到项目>连接到源>NuGet.exe,在“项目设置”部分>源 URL 下找到
SourceLocation
链接。项目作用域的源:
Register-PSResourceRepository -Name "PowershellPSResourceRepository" ` -Uri "https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/<PROJECT_NAME>/_packaging/<FEED_NAME>/nuget/v3/index.json" ` -Trusted ` -CredentialInfo $CredentialInfo
组织作用域的源:
Register-PSResourceRepository -Name "PowershellPSResourceRepository" ` -Uri "https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/_packaging/<FEED_NAME>/nuget/v3/index.json" ` -Trusted ` -CredentialInfo $CredentialInfo
提示
某些版本的 PowerShell 可能需要在运行
Register-PSResourceRepository
cmdlet 后启动新会话,以防止遇到 无法解析包源 警告。若要验证存储库是否已成功注册,请运行以下命令以检索当前用户的所有已注册存储库:
Get-PSResourceRepository
注意
如果遇到错误:响应状态代码未指示成功: 404(找不到)。请确保源 URL 指向 nuget/v3/index.json
而不是 nuget/v2
。
发布包
运行以下命令,将包发布到源:
Publish-PSResource -Path <PACKAGE_PATH> -Repository <REPOSITORY_NAME> -ApiKey (Get-Secret <SECRET_NAME>)
示例:
PS C:\AzureDevOps\Demos\PowerShellDemo> Publish-PSResource -Path .\scripts\ -Repository FabrikamFiberFeed -ApiKey (Get-Secret MyNewCredential) -verbose
VERBOSE: Performing the operation "Publish-PSResource" on target "Publish resource
'C:\AzureDevOps\Demos\PowerShellDemo\scripts\' from the machine".
VERBOSE: The newly created nuspec is:
C:\Users\xxxx\AppData\Local\Temp\xxxxxxxxx\PowerShell-Demo.nuspec
VERBOSE: credential successfully read from vault and set for repository: FabrikamFiberFeed
VERBOSE: Successfully packed the resource into a .nupkg
VERBOSE: Successfully published the resource to
'https://pkgs.dev.azure.com/ramiMSFTDevOps/DemoProject/_packaging/FabrikamFiberFeed/nuget/v3/index.json'
VERBOSE: Deleting temporary directory 'C:\Users\xxxx\AppData\Local\Temp\xxxxxxx'
安装包
若要确认模块是否在存储库中可用,请使用以下命令搜索它:
Find-PSResource -Name <RESOURCE_NAME> -Repository <REPOSITORY_NAME> -verbose
运行以下命令以安装模块的最新稳定版本:
Install-PSResource <MODULE_NAME>
提示
如果遇到错误: 调用“WriteObject”的异常,请启动新的 PowerShell 窗口并运行 Get-SecretInfo
。 在运行 Find-PSResource 和 Install-PSResource 之前输入保管库密码,因为 SecretStore 超时期限可能会过期。 默认 PasswordTimeout 为 900 秒,但可以根据需要修改此值。 有关更多详细信息,请参阅 自动化 中的 SecretStore。
本文将指导如何进行以下操作:
- 创建个人访问令牌
- 创建、打包和发布 PowerShell 模块
- 以 PowerShell 存储库的形式连接到源
- 使用 Azure Pipelines 注册并安装 PowerShell 模块
先决条件
安装 NuGet。
创建个人访问令牌
个人访问令牌充当数字标识,充当使用 Azure DevOps 进行身份验证的替代密码。
导航到 Azure DevOps 组织
https://dev.azure.com/<ORGANIZATION_NAME>/
选择用户设置图标,选择 “个人访问令牌”,然后选择“ 新建令牌”。
输入 PAT 的名称,设置到期日期,选择“自定义”,然后选择“打包>读取”、“写入和管理”。
完成后选择“创建”,并确保将 PAT 复制并存储在安全的位置。
创建 PowerShell 模块
如果没有自己的模块,请按照本节中的说明创建示例 PowerShell 模块。 否则,请跳到下一步:
创建新文件夹 Get-Hello。 导航到文件夹并创建新文件 Get-Hello.psm1。
将以下脚本粘贴到 Get-Hello.psm1 文件中:
Function Get-Hello{ Write-Host "Hello Azure DevOps!" }
通过在 Get-Hello 目录中运行以下命令来生成模块清单:
New-ModuleManifest -Path .\Get-Hello.psd1
打开 Get-Hello.psd1 文件并找到变量
RootModule
。 此设置指定导入模块时 PowerShell 加载的主脚本文件。 将空字符串替换为 Get-Hello.psm1 文件的路径:RootModule = 'Get-Hello.psm1'
本
FunctionsToExport
部分指定导入模块时用户可以访问哪些函数。 包括 Get-Hello 函数:FunctionsToExport = @('Get-Hello')
查找节
FileList
,该节指定打包模块时包含的文件。 使用模块添加要打包的文件:FileList = @('./Get-Hello.psm1')
打包和发布模块
为模块生成 nuspec 文件。 此命令创建一个 Get-Hello.nuspec 文件,其中包含打包模块所需的元数据:
nuget spec Get-Hello
运行以下命令来打包模块:
nuget pack Get-Hello.nuspec
运行以下命令以添加源源 URL。 请确保在源 URL 中使用 V2,因为不支持 NuGet V3。
组织作用域的源:
nuget sources Add -Name "<FEED_NAME>" -Source "https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/_packaging/<FEED_NAME>/nuget/v2" -username "<USER_NAME>" -password "<PERSONAL_ACCESS_TOKEN>"
项目作用域的源:
nuget sources Add -Name "<FEED_NAME>" -Source "https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/<PROJECT_NAME>/_packaging/<FEED_NAME>/nuget/v2" -username "<USER_NAME>" -password "<PERSONAL_ACCESS_TOKEN>"
将包发布到源:
nuget push -Source "<FEED_NAME>" -ApiKey "<ANY_STRING>" "<PACKAGE_PATH>"
重要
模块清单(.psd1)中的版本号必须与 .nuspec 文件中的版本号相同。
以 PowerShell 存储库的形式连接到源
本部分将指导你使用源作为 PowerShell 存储库进行身份验证,并使用源中托管的模块:
在 PowerShell 提示窗口中,运行以下命令来设置凭据。 将占位符替换为相应的信息。
$patToken = "<PERSONAL_ACCESS_TOKEN>" | ConvertTo-SecureString -AsPlainText -Force $credsAzureDevopsServices = New-Object System.Management.Automation.PSCredential("<USER_NAME>", $patToken)
注册 PowerShell 存储库。 可以通过导航到项目>连接到源>NuGet.exe,在“项目设置”部分>源 URL 下找到
SourceLocation
链接。项目作用域的源:
Register-PSRepository -Name <REPOSITORY_NAME> -SourceLocation "https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/<PROJECT_NAME>/_packaging/<FEED_NAME>/nuget/v2" -PublishLocation "https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/<PROJECT_NAME>/_packaging/<FEED_NAME>/nuget/v2" -InstallationPolicy Trusted -Credential $credsAzureDevopsServices
组织作用域的源:
Register-PSRepository -Name <REPOSITORY_NAME> -SourceLocation "https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/_packaging/<FEED_NAME>/nuget/v2" -PublishLocation "https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/_packaging/<FEED_NAME>/nuget/v2" -InstallationPolicy Trusted -Credential $credsAzureDevopsServices
提示
某些版本的 PowerShell 可能需要在运行
Register-PSRepository
cmdlet 后启动新会话,以防止遇到 无法解析包源 警告。注册包源:
项目作用域的源:
Register-PackageSource -Name <REPOSITORY_NAME> -Location "https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/<PROJECT_NAME>/_packaging/<FEED_NAME>/nuget/v2" -ProviderName NuGet -Trusted -SkipValidate -Credential $credsAzureDevopsServices
组织作用域的源:
Register-PackageSource -Name <REPOSITORY_NAME> -Location "https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/_packaging/<FEED_NAME>/nuget/v2" -ProviderName NuGet -Trusted -SkipValidate -Credential $credsAzureDevopsServices
注意
- Register-PSRepository:用于注册 PowerShell 存储库以查找和安装模块。
- Register-PackageSource:用于注册包源以查找和发布包。
若要验证存储库是否已成功注册,请运行以下命令以检索当前用户的所有已注册存储库:
Get-PSRepository
运行以下命令以安装 Get-Hello 模块。
Install-Module -Name <PACKAGE_NAME> -Repository <REPOSITORY_NAME>
注意
如果组织使用防火墙或代理服务器,请确保允许访问 Azure Artifacts 域 URL 和 IP 地址。
从管道安装包
此示例逐步讲解如何使用 Azure Artifacts 源进行身份验证,并从管道安装 PowerShell 模块。 若要使用个人访问令牌,请将其添加为管道变量,如下所示:
登录到 Azure DevOps 组织,并导航到你的项目。
选择 管道,选择管道定义,然后选择“ 编辑” 以修改管道。
选择 右上角的“变量 ”,然后选择“ 新建变量”。
输入变量的名称,然后将个人访问令牌粘贴到“值”文本框中。
请确保选中“ 保留此值机密 ”复选框。 完成后,选择“ 确定 ”。
为 userName 添加第二个变量。 输入变量的名称,然后在“值”文本框中输入 userName。
完成时选择保存。
trigger:
- main
pool:
vmImage: 'Windows-latest'
variables:
PackageFeedEndpoint: 'https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/<PROJECT_NAME>/_packaging/<FEED_NAME>/nuget/v2' ## For organization scoped feeds use'https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/_packaging/<FEED_NAME>/nuget/v2'
steps:
- powershell: |
$pat = ConvertTo-SecureString ${env:pat_token} -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential("${env:userName}", $pat)
Register-PSRepository -Name <REPOSITORY_NAME> -SourceLocation "$(PackageFeedEndpoint)" -InstallationPolicy Trusted -Credential $credential
displayName: 'Register PSRepository'
env:
pat_token: $patToken
userName: $userName
- powershell: |
nuget install <PACKAGE_NAME> -Source "https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/<PROJECT_NAME>/_packaging/<FEED_NAME>/nuget/v3/index.json"
displayName: 'Install module'