|
| 1 | +function Register-ADOArtifactFeed |
| 2 | +{ |
| 3 | + <# |
| 4 | + .Synopsis |
| 5 | + Registers an Azure DevOps artifact feed. |
| 6 | + .Description |
| 7 | + Registers an Azure DevOps artifact feed as a PowerShell Repository. |
| 8 | + thThis allows Install-Module, Publish-Module, and Save-Module to work against an Azure DevOps artifact feed. |
| 9 | + .Example |
| 10 | + Register-ADOArtifactFeed -Organization MyOrg -Project MyProject -Name MyFeed -PersonalAccessToken $myPat |
| 11 | + .Link |
| 12 | + https://docs.microsoft.com/en-us/azure/devops/artifacts/tutorials/private-powershell-library?view=azure-devops |
| 13 | + .Link |
| 14 | + Get-ADOArtifactFeed |
| 15 | + .Link |
| 16 | + Unregister-ADOArtifactFeed |
| 17 | + .Link |
| 18 | + Get-PSRepository |
| 19 | + .Link |
| 20 | + Register-PSRepository |
| 21 | + .Link |
| 22 | + Unregister-PSRepository |
| 23 | + #> |
| 24 | + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "", |
| 25 | + Justification="Abstracting Credential Structure is part of the point")] |
| 26 | + [OutputType('Microsoft.PowerShell.Commands.PSRepository')] |
| 27 | + param( |
| 28 | + # The name of the organization. |
| 29 | + [Parameter(Mandatory,ValueFromPipelineByPropertyName)] |
| 30 | + [string] |
| 31 | + $Organization, |
| 32 | + |
| 33 | + # The Project |
| 34 | + [Parameter(ValueFromPipelineByPropertyName)] |
| 35 | + [string] |
| 36 | + $Project, |
| 37 | + |
| 38 | + # The name or ID of the feed. |
| 39 | + [Parameter(Mandatory,ValueFromPipelineByPropertyName)] |
| 40 | + [string] |
| 41 | + $Name, |
| 42 | + |
| 43 | + # The personal access token used to connect to the feed. |
| 44 | + [Parameter(ValueFromPipelineByPropertyName)] |
| 45 | + [Alias('PAT')] |
| 46 | + [string] |
| 47 | + $PersonalAccessToken, |
| 48 | + |
| 49 | + # The email address used to connect |
| 50 | + [Parameter(ValueFromPipelineByPropertyName)] |
| 51 | + [string] |
| 52 | + $EmailAddress, |
| 53 | + |
| 54 | + # If provided, will create a repository source using a given name. |
| 55 | + # By default, the RepositoryName will be $Organization-$Project-$Name |
| 56 | + [Parameter(ValueFromPipelineByPropertyName)] |
| 57 | + [string] |
| 58 | + $RepositoryName, |
| 59 | + |
| 60 | + # If provided, will create a repository using a given URL. |
| 61 | + # By default, the RepositoryURL is predicted using -Organization, -Project, and -Name |
| 62 | + [Parameter(ValueFromPipelineByPropertyName)] |
| 63 | + [string] |
| 64 | + $RepositoryUrl, |
| 65 | + |
| 66 | + # If set, will remove the connection to an existing feed and then create a new one. |
| 67 | + [switch] |
| 68 | + $Force |
| 69 | + ) |
| 70 | + |
| 71 | + |
| 72 | + begin { |
| 73 | + $psRepos = Get-PSRepository |
| 74 | + } |
| 75 | + process { |
| 76 | + #region Check if Repository Already Exists |
| 77 | + $targetName = if ($RepositoryName) { $RepositoryName } |
| 78 | + elseif ($Project) { "${Organization}-${Project}-${Name}" } |
| 79 | + else { "${Organization}-${Name}" } |
| 80 | + $targetSource = if ($RepositoryUrl) { $RepositoryUrl } |
| 81 | + elseif ($Project) { "https://pkgs.dev.azure.com/$Organization/$Project/_packaging/$Name/nuget/v2" } |
| 82 | + else { "https://pkgs.dev.azure.com/$Organization/_packaging/$Name/nuget/v2" } |
| 83 | + $psRepoExists = $psRepos | |
| 84 | + Where-Object { |
| 85 | + $_.Name -eq $targetName -or |
| 86 | + $_.SourceLocation -eq $targetSource |
| 87 | + } |
| 88 | + |
| 89 | + if ($psRepoExists -and $Force) { |
| 90 | + $psRepoExists | Unregister-PSRepository |
| 91 | + } elseif ($psRepoExists) { |
| 92 | + Write-Verbose "Repository already exists: $($psRepoExists.Name)" |
| 93 | + return $psRepoExists |
| 94 | + } |
| 95 | + #endregion Check if Repository Already Exists |
| 96 | + |
| 97 | + #region Create Credential and Register-PSRepository |
| 98 | + if (-not $PersonalAccessToken -and $env:SYSTEM_ACCESSTOKEN) { |
| 99 | + $PersonalAccessToken = $env:SYSTEM_ACCESSTOKEN |
| 100 | + } |
| 101 | + |
| 102 | + if (-not $EmailAddress -and $PersonalAccessToken) { |
| 103 | + $EmailAddress = $PersonalAccessToken |
| 104 | + } |
| 105 | + |
| 106 | + if (-not $EmailAddress -and -not $PersonalAccessToken) { |
| 107 | + Write-Error "Must provide a -PersonalAccessToken. Should provide an -EmailAddress" |
| 108 | + return |
| 109 | + } |
| 110 | + |
| 111 | + $repoCred = [Management.Automation.PSCredential]::new($EmailAddress, (ConvertTo-SecureString -AsPlainText -Force $PersonalAccessToken)) |
| 112 | + |
| 113 | + Register-PSRepository -Name $targetName -SourceLocation $targetSource -PublishLocation $targetSource -InstallationPolicy Trusted -Credential $repoCred |
| 114 | + if ($?) { |
| 115 | + Get-PSRepository -Name $targetName |
| 116 | + } |
| 117 | + #endregion Create Credential and Register-PSRepository |
| 118 | + } |
| 119 | +} |
0 commit comments