Public/Add-VSTeamProfile.ps1
function Add-VSTeamProfile { [CmdletBinding(DefaultParameterSetName = 'Secure')] param( [parameter(ParameterSetName = 'Windows', Mandatory = $true, Position = 1)] [parameter(ParameterSetName = 'Secure', Mandatory = $true, Position = 1)] [Parameter(ParameterSetName = 'Plain')] [string] $Account, [parameter(ParameterSetName = 'Plain', Mandatory = $true, Position = 2, HelpMessage = 'Personal Access Token')] [string] $PersonalAccessToken, [parameter(ParameterSetName = 'Secure', Mandatory = $true, HelpMessage = 'Personal Access Token')] [securestring] $SecurePersonalAccessToken, [string] $Name, [ValidateSet('TFS2017', 'TFS2018', 'VSTS')] [string] $Version, [switch] $UseBearerToken ) DynamicParam { # Only add these options on Windows Machines if (_isOnWindows) { # Create the dictionary $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $ParameterName2 = 'UseWindowsAuthentication' # Create the collection of attributes $AttributeCollection2 = New-Object System.Collections.ObjectModel.Collection[System.Attribute] # Create and set the parameters' attributes $ParameterAttribute2 = New-Object System.Management.Automation.ParameterAttribute $ParameterAttribute2.Mandatory = $true $ParameterAttribute2.ParameterSetName = "Windows" $ParameterAttribute2.HelpMessage = "On Windows machines allows you to use the active user identity for authentication. Not available on other platforms." # Add the attributes to the attributes collection $AttributeCollection2.Add($ParameterAttribute2) # Create and return the dynamic parameter $RuntimeParameter2 = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName2, [switch], $AttributeCollection2) $RuntimeParameterDictionary.Add($ParameterName2, $RuntimeParameter2) return $RuntimeParameterDictionary } } process { if ($SecurePersonalAccessToken) { # Even when promoted for a Secure Personal Access Token you can just # press enter. This leads to an empty PAT so error below. # Convert the securestring to a normal string # this was the one technique that worked on Mac, Linux and Windows $_pat = _convertSecureStringTo_PlainText -SecureString $SecurePersonalAccessToken } else { $_pat = $PersonalAccessToken } if (_isOnWindows) { # Bind the parameter to a friendly variable $UsingWindowsAuth = $PSBoundParameters[$ParameterName2] if (!($_pat) -and !($UsingWindowsAuth)) { Write-Error 'Personal Access Token must be provided if you are not using Windows Authentication; please see the help.' return } } # If they only gave an account name add https://dev.azure.com if ($Account -notlike "*/*") { if (-not $Name) { $Name = $Account } $Account = "https://dev.azure.com/$($Account)" } # If they gave https://dev.azure.com extract Account and Profile name if ($Account -match "(?<protocol>https\://)?(?<domain>dev\.azure\.com/)(?<account>[A-Z0-9][-A-Z0-9]*[A-Z0-9])") { if (-not $Name) { $Name = $matches.account } $Account = "https://dev.azure.com/$($matches.account)" } # If they gave https://xxx.visualstudio.com extract Account and Profile name, convert to new URL if ($Account -match "(?<protocol>https?\://)?(?<account>[A-Z0-9][-A-Z0-9]*[A-Z0-9])(?<domain>\.visualstudio\.com)") { if (-not $Name) { $Name = $matches.account } $Account = "https://dev.azure.com/$($matches.account)" } if ($UseBearerToken.IsPresent) { $authType = 'Bearer' $token = $_pat $encodedPat = '' } else { $token = '' $authType = 'Pat' $encodedPat = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$_pat")) } # If no SecurePersonalAccessToken is entered, and on windows, are we using default credentials for REST calls if ((!$_pat) -and (_isOnWindows) -and ($UsingWindowsAuth)) { Write-Verbose 'Using Default Windows Credentials for authentication; no Personal Access Token required' $encodedPat = '' $token = '' $authType = 'OnPremise' } if (-not $Name) { $Name = $Account } # See if this item is already in there # I am testing URL because the user may provide a different # name and I don't want two with the same URL. # The @() forces even 1 item to an array $profiles = @(Get-VSTeamProfile | Where-Object URL -ne $Account) $newProfile = [PSCustomObject]@{ Name = $Name URL = $Account Type = $authType Pat = $encodedPat Token = $token Version = (_getVSTeamAPIVersion -Instance $Account -Version $Version) } $profiles += $newProfile $contents = ConvertTo-Json $profiles Set-Content -Path $profilesPath -Value $contents } } |