diff --git a/Tasks/AzureCloudPowerShellDeploymentV1/task.json b/Tasks/AzureCloudPowerShellDeploymentV1/task.json index 0d4ecadd53ee..fb4b342f0f79 100644 --- a/Tasks/AzureCloudPowerShellDeploymentV1/task.json +++ b/Tasks/AzureCloudPowerShellDeploymentV1/task.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 218, + "Minor": 221, "Patch": 0 }, "demands": [ diff --git a/Tasks/AzureCloudPowerShellDeploymentV1/task.loc.json b/Tasks/AzureCloudPowerShellDeploymentV1/task.loc.json index 95d87acb2ab2..fc48744f6700 100644 --- a/Tasks/AzureCloudPowerShellDeploymentV1/task.loc.json +++ b/Tasks/AzureCloudPowerShellDeploymentV1/task.loc.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 218, + "Minor": 221, "Patch": 0 }, "demands": [ diff --git a/Tasks/AzureFileCopyV1/AzureFileCopy.ps1 b/Tasks/AzureFileCopyV1/AzureFileCopy.ps1 index 82c482f978b2..59ee2a811ae7 100644 --- a/Tasks/AzureFileCopyV1/AzureFileCopy.ps1 +++ b/Tasks/AzureFileCopyV1/AzureFileCopy.ps1 @@ -92,14 +92,17 @@ try { # Getting connection type (Certificate/UserNamePassword/SPN) used for the task $connectionType = Get-TypeOfConnection -connectedServiceName $connectedServiceName + $vstsEndpoint = Get-VstsEndpoint -Name SystemVssConnection -Require + $vstsAccessToken = $vstsEndpoint.auth.parameters.AccessToken + # Getting storage key for the storage account based on the connection type - $storageKey = Get-StorageKey -storageAccountName $storageAccount -connectionType $connectionType -connectedServiceName $connectedServiceName + $storageKey = Get-StorageKey -storageAccountName $storageAccount -connectionType $connectionType -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken # creating storage context to be used while creating container, sas token, deleting container $storageContext = Create-AzureStorageContext -StorageAccountName $storageAccount -StorageAccountKey $storageKey - + # Geting Azure Storage Account type - $storageAccountType = Get-StorageAccountType -storageAccountName $storageAccount -connectionType $connectionType -connectedServiceName $connectedServiceName + $storageAccountType = Get-StorageAccountType $storageAccount $connectionType $connectedServiceName $vstsAccessToken Write-Verbose "Obtained Storage Account type: $storageAccountType" if(-not [string]::IsNullOrEmpty($storageAccountType) -and $storageAccountType.Contains('Premium')) { @@ -169,11 +172,12 @@ try { # Normalize admin username if($vmsAdminUserName -and (-not $vmsAdminUserName.StartsWith(".\")) -and ($vmsAdminUserName.IndexOf("\") -eq -1) -and ($vmsAdminUserName.IndexOf("@") -eq -1)) { - $vmsAdminUserName = ".\" + $vmsAdminUserName + $vmsAdminUserName = ".\" + $vmsAdminUserName } # getting azure vms properties(name, fqdn, winrmhttps port) $azureVMResourcesProperties = Get-AzureVMResourcesProperties -resourceGroupName $environmentName -connectionType $connectionType ` - -resourceFilteringMethod $resourceFilteringMethod -machineNames $machineNames -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName + -resourceFilteringMethod $resourceFilteringMethod -machineNames $machineNames -enableCopyPrerequisites $enableCopyPrerequisites ` + -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken $skipCACheckOption = Get-SkipCACheckOption -skipCACheck $skipCACheck $azureVMsCredentials = Get-AzureVMsCredentials -vmsAdminUserName $vmsAdminUserName -vmsAdminPassword $vmsAdminPassword diff --git a/Tasks/AzureFileCopyV1/AzureUtilityGTE1.0.ps1 b/Tasks/AzureFileCopyV1/AzureUtilityGTE1.0.ps1 index d0e0a30d576e..e161e00a6373 100644 --- a/Tasks/AzureFileCopyV1/AzureUtilityGTE1.0.ps1 +++ b/Tasks/AzureFileCopyV1/AzureUtilityGTE1.0.ps1 @@ -100,7 +100,9 @@ function Get-AzureBlobStorageEndpointFromRDFE function Get-AzureBlobStorageEndpointFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -135,7 +137,9 @@ function Get-AzureStorageAccountTypeFromRDFE function Get-AzureStorageAccountTypeFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -288,26 +292,28 @@ function Get-AzureRMVMsInResourceGroup function Get-AzureRMResourceGroupResourcesDetailsForAzureStack { param([string]$resourceGroupName, - [object]$azureRMVMResources, - [object]$endpoint) + [object]$azureRMVMResources, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) [hashtable]$azureRGResourcesDetails = @{} [hashtable]$loadBalancerDetails = @{} - + if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureNetworkInterfaceDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $networkInterfaceResources = Get-AzureNetworkInterfaceDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzurePublicIpAddressDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $publicIPAddressResources = Get-AzurePublicIpAddressDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureLoadBalancersDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $lbGroup = Get-AzureLoadBalancersDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -316,7 +322,7 @@ function Get-AzureRMResourceGroupResourcesDetailsForAzureStack { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureLoadBalancerDetails -Name $lb.Name -ResourceGroupName $resourceGroupName -endpoint $endpoint + $loadBalancer = Get-AzureLoadBalancerDetails $resourceGroupName $lb.Name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" @@ -421,24 +427,26 @@ function Get-AzureMachineStatus $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } - + return $status } function Get-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName)) { Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtension" -ArgumentList $name, $vmName) - $customScriptExtension = Get-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + $customScriptExtension = Get-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } - + return $customScriptExtension } @@ -455,24 +463,26 @@ function Set-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } - + return $result } function Remove-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtension" -ArgumentList $name, $vmName) - $response = Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + $response = Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } diff --git a/Tasks/AzureFileCopyV1/AzureUtilityLTE9.8.ps1 b/Tasks/AzureFileCopyV1/AzureUtilityLTE9.8.ps1 index 2eec6372d0eb..a8ba50244ae5 100644 --- a/Tasks/AzureFileCopyV1/AzureUtilityLTE9.8.ps1 +++ b/Tasks/AzureFileCopyV1/AzureUtilityLTE9.8.ps1 @@ -106,7 +106,9 @@ function Get-AzureBlobStorageEndpointFromRDFE function Get-AzureBlobStorageEndpointFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -145,7 +147,9 @@ function Get-AzureStorageAccountTypeFromRDFE function Get-AzureStorageAccountTypeFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -391,25 +395,27 @@ function Get-AzureMachineStatus $status = Get-AzureVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } - + return $status } function Get-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) Switch-AzureMode AzureResourceManager if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName)) { Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtension" -ArgumentList $name, $vmName) - $customScriptExtension = Get-AzureVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + $customScriptExtension = Get-AzureVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } - + return $customScriptExtension } @@ -427,25 +433,27 @@ function Set-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) - $result = Set-AzureVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + $result = Set-AzureVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } - + return $result } function Remove-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) Switch-AzureMode AzureResourceManager if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtension" -ArgumentList $name, $vmName) - $response = Remove-AzureVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + $response = Remove-AzureVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } diff --git a/Tasks/AzureFileCopyV1/AzureUtilityRest.ps1 b/Tasks/AzureFileCopyV1/AzureUtilityRest.ps1 index 044dcf074c55..516b7243995d 100644 --- a/Tasks/AzureFileCopyV1/AzureUtilityRest.ps1 +++ b/Tasks/AzureFileCopyV1/AzureUtilityRest.ps1 @@ -20,7 +20,9 @@ function Get-AzureStorageKeyFromRDFE function Get-AzureStorageKeyFromARM { param([string]$storageAccountName, - [object]$serviceEndpoint) + [object]$serviceEndpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) if (-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -28,8 +30,8 @@ function Get-AzureStorageKeyFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage key for the storage account: $storageAccount in resource group: $azureResourceid" - - $storageKeyDetails = Get-AzRMStorageKeys $azureResourceGroupName $storageAccountName $serviceEndpoint + + $storageKeyDetails = Get-AzRMStorageKeys $azureResourceGroupName $storageAccountName $serviceEndpoint $connectedServiceNameARM $vstsAccessToken $storageKey = $storageKeyDetails.Key1 Write-Verbose "[Azure Call]Retrieved storage key successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -60,7 +62,9 @@ function Get-AzureBlobStorageEndpointFromRDFE function Get-AzureBlobStorageEndpointFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -68,13 +72,13 @@ function Get-AzureBlobStorageEndpointFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account endpoint for the storage account: $storageAccount in resource group: $azureResourceGroupName" - - $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint -ErrorAction Stop + + $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken -ErrorAction Stop $storageAccountEnpoint = $storageAccountInfo.PrimaryEndpoints[0].blob Write-Verbose "[Azure Call]Retrieved storage account endpoint successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" return $storageAccountEnpoint - } + } } function Get-AzureStorageAccountTypeFromRDFE @@ -96,7 +100,9 @@ function Get-AzureStorageAccountTypeFromRDFE function Get-AzureStorageAccountTypeFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -104,42 +110,46 @@ function Get-AzureStorageAccountTypeFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account type for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint -ErrorAction Stop + $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken -ErrorAction Stop $storageAccountType = $storageAccountInfo.sku.tier Write-Verbose "[Azure Call]Retrieved storage account type successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" return $storageAccountType - } + } } function Get-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName)) { Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtension" -ArgumentList $name, $vmName) - $customScriptExtension = Get-AzRmVmCustomScriptExtension $resourceGroupName $vmName $name $endpoint + $customScriptExtension = Get-AzRmVmCustomScriptExtension $resourceGroupName $vmName $name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } - + return $customScriptExtension } function Remove-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtension" -ArgumentList $name, $vmName) - $response = Remove-AzRmVMCustomScriptExtension $resourceGroupName $vmName $name $endpoint + $response = Remove-AzRmVMCustomScriptExtension $resourceGroupName $vmName $name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } diff --git a/Tasks/AzureFileCopyV1/IAzureUtility.ps1 b/Tasks/AzureFileCopyV1/IAzureUtility.ps1 index e54f2ee54a8e..777923782ad4 100644 --- a/Tasks/AzureFileCopyV1/IAzureUtility.ps1 +++ b/Tasks/AzureFileCopyV1/IAzureUtility.ps1 @@ -17,7 +17,9 @@ function Get-AzureStorageAccountResourceGroupName function Get-AzureStorageKeyFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) } # creates azureStorageContext object for given storageaccount and storagekey @@ -39,14 +41,18 @@ function Get-AzureBlobStorageEndpointFromRDFE function Get-AzureBlobStorageEndpointFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) } # return account type for given ARM storage account function Get-AzureStorageAccountTypeFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) } # return account type for given classic storage account @@ -128,9 +134,11 @@ function Get-AzureMachineStatus function Get-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) } # Returns details of the custom script extension $name executed on VM $vmName present in ResourceGroup $resourceGroupName @@ -149,7 +157,9 @@ function Set-AzureMachineCustomScriptExtension function Remove-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) } \ No newline at end of file diff --git a/Tasks/AzureFileCopyV1/Utility.ps1 b/Tasks/AzureFileCopyV1/Utility.ps1 index 49a59ecd6f87..ad9b150f806d 100644 --- a/Tasks/AzureFileCopyV1/Utility.ps1 +++ b/Tasks/AzureFileCopyV1/Utility.ps1 @@ -121,8 +121,9 @@ function Validate-AzurePowershellVersion function Get-StorageKey { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [string][Parameter(Mandatory=$true)]$connectionType, - [string][Parameter(Mandatory=$true)]$connectedServiceName) + [string][Parameter(Mandatory=$true)]$connectionType, + [string][Parameter(Mandatory=$true)]$connectedServiceName, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) $serviceEndpoint = Get-Endpoint $connectedServiceName $storageAccountName = $storageAccountName.Trim() @@ -170,7 +171,8 @@ function Get-StorageKey Validate-AzurePowershellVersion # getting storage account key from ARM endpoint - $storageKey = Get-AzureStorageKeyFromARM -storageAccountName $storageAccountName -serviceEndpoint $serviceEndpoint + $storageKey = Get-AzureStorageKeyFromARM -storageAccountName $storageAccountName -serviceEndpoint $serviceEndpoint ` + -connectedServiceNameARM $connectedServiceName $vstsAccessToken } return $storageKey @@ -179,9 +181,10 @@ function Get-StorageKey function Get-blobStorageEndpoint { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [string][Parameter(Mandatory=$true)]$connectionType, - [string][Parameter(Mandatory=$true)]$connectedServiceName) - + [string][Parameter(Mandatory=$true)]$connectionType, + [string][Parameter(Mandatory=$true)]$connectedServiceName, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) + $endpoint = Get-Endpoint $connectedServiceName $storageAccountName = $storageAccountName.Trim() if($connectionType -eq 'Certificate' -or $connectionType -eq 'UserNamePassword') @@ -202,7 +205,7 @@ function Get-blobStorageEndpoint else { # getting storage account key from ARM endpoint - $blobStorageEndpoint = Get-AzureBlobStorageEndpointFromARM -storageAccountName $storageAccountName -endpoint $endpoint + $blobStorageEndpoint = Get-AzureBlobStorageEndpointFromARM $storageAccountName $endpoint $connectedServiceName $vstsAccessToken } return $blobStorageEndpoint @@ -211,8 +214,9 @@ function Get-blobStorageEndpoint function Get-StorageAccountType { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [string][Parameter(Mandatory=$true)]$connectionType, - [string][Parameter(Mandatory=$true)]$connectedServiceName) + [string][Parameter(Mandatory=$true)]$connectionType, + [string][Parameter(Mandatory=$true)]$connectedServiceName, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) $endpoint = Get-Endpoint $connectedServiceName $storageAccountName = $storageAccountName.Trim() @@ -234,10 +238,10 @@ function Get-StorageAccountType else { # getting storage account type from ARM endpoint - $storageAccountType = Get-AzureStorageAccountTypeFromARM -storageAccountName $storageAccountName -endpoint $endpoint + $storageAccountType = Get-AzureStorageAccountTypeFromARM $storageAccountName $endpoint $connectedServiceName $vstsAccessToken } - if($storageAccountType -ne $null) + if($null -ne $storageAccountType) { return $storageAccountType.ToString() } @@ -765,7 +769,8 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup param([string]$resourceGroupName, [object]$azureRMVMResources, [string]$enableCopyPrerequisites, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) [hashtable]$fqdnMap = @{} $winRMHttpsPortMap = New-Object 'System.Collections.Generic.Dictionary[string, string]' @@ -789,13 +794,14 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup if (-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { - - if($isAzureStackEnvironment) + + if($isAzureStackEnvironment) { Write-Verbose "Fetching resource group resources details for Azure Stack environment." - $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetailsForAzureStack -resourceGroupName $resourceGroupName -azureRMVMResources $azureRMVMResources -endpoint $endpoint + $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetailsForAzureStack -resourceGroupName $resourceGroupName ` + -azureRMVMResources $azureRMVMResources -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken } - else + else { Write-Verbose "Fetching resource group resources details for Azure/National cloud environments." $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetails -resourceGroupName $resourceGroupName -azureRMVMResources $azureRMVMResources @@ -850,7 +856,8 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup if ($enableCopyPrerequisites -eq "true") { Write-Verbose "Enabling winrm for virtual machine $resourceName" -Verbose - Add-AzureVMCustomScriptExtension -resourceGroupName $resourceGroupName -vmId $resourceId -vmName $resourceName -dnsName $resourceFQDN -location $resource.Location -connectedServiceName $connectedServiceName + Add-AzureVMCustomScriptExtension -resourceGroupName $resourceGroupName -vmId $resourceId -vmName $resourceName -dnsName $resourceFQDN ` + -location $resource.Location -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken } } @@ -891,7 +898,8 @@ function Get-AzureVMResourcesProperties [string]$resourceFilteringMethod, [string]$machineNames, [string]$enableCopyPrerequisites, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $machineNames = $machineNames.Trim() if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($connectionType)) @@ -918,7 +926,8 @@ function Get-AzureVMResourcesProperties { $azureRMVMResources = Get-AzureRMVMsInResourceGroup -resourceGroupName $resourceGroupName $filteredAzureRMVMResources = Get-FilteredAzureRMVMsInResourceGroup -azureRMVMResources $azureRMVMResources -resourceFilteringMethod $resourceFilteringMethod -filter $machineNames - $azureVMsDetails = Get-AzureRMVMsConnectionDetailsInResourceGroup -resourceGroupName $resourceGroupName -azureRMVMResources $filteredAzureRMVMResources -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName + $azureVMsDetails = Get-AzureRMVMsConnectionDetailsInResourceGroup -resourceGroupName $resourceGroupName -azureRMVMResources $filteredAzureRMVMResources ` + -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken } # throw if no azure VMs found in resource group or due to filtering @@ -1173,9 +1182,11 @@ function Copy-FilesToAzureVMsFromStorageContainer function Validate-CustomScriptExecutionStatus { param([string]$resourceGroupName, - [string]$vmName, - [string]$extensionName, - [object]$endpoint) + [string]$vmName, + [string]$extensionName, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) Write-Verbose "Validating the winrm configuration custom script extension status" @@ -1215,18 +1226,19 @@ function Validate-CustomScriptExecutionStatus else { $isScriptExecutionPassed = $false - $errMessage = "No custom script extension '$extensionName' exists" + $errMessage = "No custom script extension '$extensionName' exists" } } catch { $isScriptExecutionPassed = $false - $errMessage = $_.Exception.Message + $errMessage = $_.Exception.Message } if(-not $isScriptExecutionPassed) { - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $endpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $endpoint -connectedServiceNameARM $connectedServiceNameARM -vstsAccessToken $vstsAccessToken throw (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionFailed" -ArgumentList $extensionName, $vmName, $errMessage) } @@ -1238,7 +1250,8 @@ function Is-WinRMCustomScriptExtensionExists param([string]$resourceGroupName, [string]$vmName, [string]$extensionName, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $isExtensionExists = $true $removeExtension = $false @@ -1246,13 +1259,14 @@ function Is-WinRMCustomScriptExtensionExists try { $serviceEndpoint=Get-Endpoint $connectedServiceName - $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken if($customScriptExtension) { if($customScriptExtension.ProvisioningState -ne "Succeeded") - { - $removeExtension = $true + { + $removeExtension = $true } else { @@ -1273,13 +1287,14 @@ function Is-WinRMCustomScriptExtensionExists } catch { - $isExtensionExists = $false + $isExtensionExists = $false } if($removeExtension) { - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint - + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken + try { $index = 1 @@ -1288,13 +1303,14 @@ function Is-WinRMCustomScriptExtensionExists while($index -le $maxCount) { Write-Verbose "Checking WinRM custom script extension status $index times" - $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken - if(-not $customScriptExtension -or $customScriptExtension.ProvisioningState -ne "deleting") + if(-not $customScriptExtension -or $customScriptExtension.ProvisioningState -ne "deleting") { break } - + start-sleep -s 20 $index = $index + 1 } @@ -1382,7 +1398,8 @@ function Add-AzureVMCustomScriptExtension [string]$vmName, [string]$dnsName, [string]$location, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $configWinRMScriptFileFwdLink ="https://aka.ms/vstsconfigurewinrm" $makeCertFileFwdLink ="https://aka.ms/vstsmakecertexe" @@ -1399,13 +1416,14 @@ function Add-AzureVMCustomScriptExtension try { $endpoint = Get-Endpoint $connectedServiceName - $isExtensionExists = Is-WinRMCustomScriptExtensionExists -resourceGroupName $resourceGroupName -vmName $vmName -extensionName $extensionName -connectedServiceName $connectedServiceName + $isExtensionExists = Is-WinRMCustomScriptExtensionExists -resourceGroupName $resourceGroupName -vmName $vmName -extensionName $extensionName ` + -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken Write-Verbose -Verbose "IsExtensionExists: $isExtensionExists" if($isExtensionExists) - { + { Add-WinRMHttpsNetworkSecurityRuleConfig -resourceGroupName $resourceGroupName -vmId $vmId -ruleName $ruleName -rulePriotity $rulePriotity -winrmHttpsPort $winrmHttpsPort - + Write-Verbose "Skipping the addition of custom script extension '$extensionName' as it already exists" return } @@ -1419,9 +1437,10 @@ function Add-AzureVMCustomScriptExtension if($result.Status -ne "Succeeded") { - Write-Telemetry "Task_InternalError" "ProvisionVmCustomScriptFailed" + Write-Telemetry "Task_InternalError" "ProvisionVmCustomScriptFailed" - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $endpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken throw (Get-VstsLocString -Key "AFC_UnableToSetCustomScriptExtension" -ArgumentList $extensionName, $vmName, $result.Error.Message) } diff --git a/Tasks/AzureFileCopyV2/AzureFileCopy.ps1 b/Tasks/AzureFileCopyV2/AzureFileCopy.ps1 index ab3bad4d302b..13b839688ad2 100644 --- a/Tasks/AzureFileCopyV2/AzureFileCopy.ps1 +++ b/Tasks/AzureFileCopyV2/AzureFileCopy.ps1 @@ -99,14 +99,17 @@ try { # Getting connection type (Certificate/UserNamePassword/SPN) used for the task $connectionType = Get-TypeOfConnection -connectedServiceName $connectedServiceName + $vstsEndpoint = Get-VstsEndpoint -Name SystemVssConnection -Require + $vstsAccessToken = $vstsEndpoint.auth.parameters.AccessToken + # Getting storage key for the storage account based on the connection type - $storageKey = Get-StorageKey -storageAccountName $storageAccount -connectionType $connectionType -connectedServiceName $connectedServiceName + $storageKey = Get-StorageKey -storageAccountName $storageAccount -connectionType $connectionType -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken # creating storage context to be used while creating container, sas token, deleting container $storageContext = Create-AzureStorageContext -StorageAccountName $storageAccount -StorageAccountKey $storageKey - + # Geting Azure Storage Account type - $storageAccountType = Get-StorageAccountType -storageAccountName $storageAccount -connectionType $connectionType -connectedServiceName $connectedServiceName + $storageAccountType = Get-StorageAccountType $storageAccount $connectionType $connectedServiceName $vstsAccessToken Write-Verbose "Obtained Storage Account type: $storageAccountType" if(-not [string]::IsNullOrEmpty($storageAccountType) -and $storageAccountType.Contains('Premium')) { @@ -208,11 +211,12 @@ try { # Normalize admin username if($vmsAdminUserName -and (-not $vmsAdminUserName.StartsWith(".\")) -and ($vmsAdminUserName.IndexOf("\") -eq -1) -and ($vmsAdminUserName.IndexOf("@") -eq -1)) { - $vmsAdminUserName = ".\" + $vmsAdminUserName + $vmsAdminUserName = ".\" + $vmsAdminUserName } # getting azure vms properties(name, fqdn, winrmhttps port) $azureVMResourcesProperties = Get-AzureVMResourcesProperties -resourceGroupName $environmentName -connectionType $connectionType ` - -resourceFilteringMethod $resourceFilteringMethod -machineNames $machineNames -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName + -resourceFilteringMethod $resourceFilteringMethod -machineNames $machineNames -enableCopyPrerequisites $enableCopyPrerequisites ` + -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken $azureVMsCredentials = Get-AzureVMsCredentials -vmsAdminUserName $vmsAdminUserName -vmsAdminPassword $vmsAdminPassword diff --git a/Tasks/AzureFileCopyV2/AzureUtilityGTE1.0.ps1 b/Tasks/AzureFileCopyV2/AzureUtilityGTE1.0.ps1 index f80107396344..3b9642fcf36c 100644 --- a/Tasks/AzureFileCopyV2/AzureUtilityGTE1.0.ps1 +++ b/Tasks/AzureFileCopyV2/AzureUtilityGTE1.0.ps1 @@ -92,7 +92,9 @@ function Get-AzureBlobStorageEndpointFromRDFE function Get-AzureBlobStorageEndpointFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -127,7 +129,9 @@ function Get-AzureStorageAccountTypeFromRDFE function Get-AzureStorageAccountTypeFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -280,26 +284,28 @@ function Get-AzureRMVMsInResourceGroup function Get-AzureRMResourceGroupResourcesDetailsForAzureStack { param([string]$resourceGroupName, - [object]$azureRMVMResources, - [object]$endpoint) + [object]$azureRMVMResources, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) [hashtable]$azureRGResourcesDetails = @{} [hashtable]$loadBalancerDetails = @{} - + if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureNetworkInterfaceDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $networkInterfaceResources = Get-AzureNetworkInterfaceDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzurePublicIpAddressDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $publicIPAddressResources = Get-AzurePublicIpAddressDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureLoadBalancersDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $lbGroup = Get-AzureLoadBalancersDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -308,7 +314,7 @@ function Get-AzureRMResourceGroupResourcesDetailsForAzureStack { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureLoadBalancerDetails -Name $lb.Name -ResourceGroupName $resourceGroupName -endpoint $endpoint + $loadBalancer = Get-AzureLoadBalancerDetails $resourceGroupName $lb.Name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" @@ -413,24 +419,26 @@ function Get-AzureMachineStatus $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } - + return $status } function Get-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName)) { Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtension" -ArgumentList $name, $vmName) - $customScriptExtension = Get-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + $customScriptExtension = Get-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } - + return $customScriptExtension } @@ -447,24 +455,26 @@ function Set-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } - + return $result } function Remove-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtension" -ArgumentList $name, $vmName) - $response = Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + $response = Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } diff --git a/Tasks/AzureFileCopyV2/AzureUtilityLTE9.8.ps1 b/Tasks/AzureFileCopyV2/AzureUtilityLTE9.8.ps1 index 2eec6372d0eb..dcdd33a0c368 100644 --- a/Tasks/AzureFileCopyV2/AzureUtilityLTE9.8.ps1 +++ b/Tasks/AzureFileCopyV2/AzureUtilityLTE9.8.ps1 @@ -52,7 +52,9 @@ function Get-AzureStorageAccountResourceGroupName function Get-AzureStorageKeyFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -106,7 +108,9 @@ function Get-AzureBlobStorageEndpointFromRDFE function Get-AzureBlobStorageEndpointFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -145,7 +149,9 @@ function Get-AzureStorageAccountTypeFromRDFE function Get-AzureStorageAccountTypeFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -391,25 +397,27 @@ function Get-AzureMachineStatus $status = Get-AzureVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } - + return $status } function Get-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) Switch-AzureMode AzureResourceManager if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName)) { Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtension" -ArgumentList $name, $vmName) - $customScriptExtension = Get-AzureVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + $customScriptExtension = Get-AzureVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } - + return $customScriptExtension } @@ -427,25 +435,27 @@ function Set-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) - $result = Set-AzureVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + $result = Set-AzureVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } - + return $result } function Remove-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) Switch-AzureMode AzureResourceManager if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtension" -ArgumentList $name, $vmName) - $response = Remove-AzureVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + $response = Remove-AzureVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } diff --git a/Tasks/AzureFileCopyV2/AzureUtilityRest.ps1 b/Tasks/AzureFileCopyV2/AzureUtilityRest.ps1 index 044dcf074c55..516b7243995d 100644 --- a/Tasks/AzureFileCopyV2/AzureUtilityRest.ps1 +++ b/Tasks/AzureFileCopyV2/AzureUtilityRest.ps1 @@ -20,7 +20,9 @@ function Get-AzureStorageKeyFromRDFE function Get-AzureStorageKeyFromARM { param([string]$storageAccountName, - [object]$serviceEndpoint) + [object]$serviceEndpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) if (-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -28,8 +30,8 @@ function Get-AzureStorageKeyFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage key for the storage account: $storageAccount in resource group: $azureResourceid" - - $storageKeyDetails = Get-AzRMStorageKeys $azureResourceGroupName $storageAccountName $serviceEndpoint + + $storageKeyDetails = Get-AzRMStorageKeys $azureResourceGroupName $storageAccountName $serviceEndpoint $connectedServiceNameARM $vstsAccessToken $storageKey = $storageKeyDetails.Key1 Write-Verbose "[Azure Call]Retrieved storage key successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -60,7 +62,9 @@ function Get-AzureBlobStorageEndpointFromRDFE function Get-AzureBlobStorageEndpointFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -68,13 +72,13 @@ function Get-AzureBlobStorageEndpointFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account endpoint for the storage account: $storageAccount in resource group: $azureResourceGroupName" - - $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint -ErrorAction Stop + + $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken -ErrorAction Stop $storageAccountEnpoint = $storageAccountInfo.PrimaryEndpoints[0].blob Write-Verbose "[Azure Call]Retrieved storage account endpoint successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" return $storageAccountEnpoint - } + } } function Get-AzureStorageAccountTypeFromRDFE @@ -96,7 +100,9 @@ function Get-AzureStorageAccountTypeFromRDFE function Get-AzureStorageAccountTypeFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -104,42 +110,46 @@ function Get-AzureStorageAccountTypeFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account type for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint -ErrorAction Stop + $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken -ErrorAction Stop $storageAccountType = $storageAccountInfo.sku.tier Write-Verbose "[Azure Call]Retrieved storage account type successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" return $storageAccountType - } + } } function Get-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName)) { Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtension" -ArgumentList $name, $vmName) - $customScriptExtension = Get-AzRmVmCustomScriptExtension $resourceGroupName $vmName $name $endpoint + $customScriptExtension = Get-AzRmVmCustomScriptExtension $resourceGroupName $vmName $name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } - + return $customScriptExtension } function Remove-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtension" -ArgumentList $name, $vmName) - $response = Remove-AzRmVMCustomScriptExtension $resourceGroupName $vmName $name $endpoint + $response = Remove-AzRmVMCustomScriptExtension $resourceGroupName $vmName $name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } diff --git a/Tasks/AzureFileCopyV2/IAzureUtility.ps1 b/Tasks/AzureFileCopyV2/IAzureUtility.ps1 index e54f2ee54a8e..777923782ad4 100644 --- a/Tasks/AzureFileCopyV2/IAzureUtility.ps1 +++ b/Tasks/AzureFileCopyV2/IAzureUtility.ps1 @@ -17,7 +17,9 @@ function Get-AzureStorageAccountResourceGroupName function Get-AzureStorageKeyFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) } # creates azureStorageContext object for given storageaccount and storagekey @@ -39,14 +41,18 @@ function Get-AzureBlobStorageEndpointFromRDFE function Get-AzureBlobStorageEndpointFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) } # return account type for given ARM storage account function Get-AzureStorageAccountTypeFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) } # return account type for given classic storage account @@ -128,9 +134,11 @@ function Get-AzureMachineStatus function Get-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) } # Returns details of the custom script extension $name executed on VM $vmName present in ResourceGroup $resourceGroupName @@ -149,7 +157,9 @@ function Set-AzureMachineCustomScriptExtension function Remove-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) } \ No newline at end of file diff --git a/Tasks/AzureFileCopyV2/Utility.ps1 b/Tasks/AzureFileCopyV2/Utility.ps1 index 6e96ac9fce6f..60e6e547d04b 100644 --- a/Tasks/AzureFileCopyV2/Utility.ps1 +++ b/Tasks/AzureFileCopyV2/Utility.ps1 @@ -97,8 +97,9 @@ function Validate-AzurePowershellVersion function Get-StorageKey { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [string][Parameter(Mandatory=$true)]$connectionType, - [string][Parameter(Mandatory=$true)]$connectedServiceName) + [string][Parameter(Mandatory=$true)]$connectionType, + [string][Parameter(Mandatory=$true)]$connectedServiceName, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) $serviceEndpoint = Get-Endpoint $connectedServiceName $storageAccountName = $storageAccountName.Trim() @@ -146,7 +147,8 @@ function Get-StorageKey Validate-AzurePowershellVersion # getting storage account key from ARM endpoint - $storageKey = Get-AzureStorageKeyFromARM -storageAccountName $storageAccountName -serviceEndpoint $serviceEndpoint + $storageKey = Get-AzureStorageKeyFromARM -storageAccountName $storageAccountName -serviceEndpoint $serviceEndpoint ` + -connectedServiceNameARM $connectedServiceName $vstsAccessToken } return $storageKey @@ -155,9 +157,10 @@ function Get-StorageKey function Get-blobStorageEndpoint { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [string][Parameter(Mandatory=$true)]$connectionType, - [string][Parameter(Mandatory=$true)]$connectedServiceName) - + [string][Parameter(Mandatory=$true)]$connectionType, + [string][Parameter(Mandatory=$true)]$connectedServiceName, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) + $endpoint = Get-Endpoint $connectedServiceName $storageAccountName = $storageAccountName.Trim() if($connectionType -eq 'Certificate' -or $connectionType -eq 'UserNamePassword') @@ -178,7 +181,7 @@ function Get-blobStorageEndpoint else { # getting storage account key from ARM endpoint - $blobStorageEndpoint = Get-AzureBlobStorageEndpointFromARM -storageAccountName $storageAccountName -endpoint $endpoint + $blobStorageEndpoint = Get-AzureBlobStorageEndpointFromARM $storageAccountName $endpoint $connectedServiceName $vstsAccessToken } return $blobStorageEndpoint @@ -187,8 +190,9 @@ function Get-blobStorageEndpoint function Get-StorageAccountType { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [string][Parameter(Mandatory=$true)]$connectionType, - [string][Parameter(Mandatory=$true)]$connectedServiceName) + [string][Parameter(Mandatory=$true)]$connectionType, + [string][Parameter(Mandatory=$true)]$connectedServiceName, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) $endpoint = Get-Endpoint $connectedServiceName $storageAccountName = $storageAccountName.Trim() @@ -210,10 +214,10 @@ function Get-StorageAccountType else { # getting storage account type from ARM endpoint - $storageAccountType = Get-AzureStorageAccountTypeFromARM -storageAccountName $storageAccountName -endpoint $endpoint + $storageAccountType = Get-AzureStorageAccountTypeFromARM $storageAccountName $endpoint $connectedServiceName $vstsAccessToken } - if($storageAccountType -ne $null) + if($null -ne $storageAccountType) { return $storageAccountType.ToString() } @@ -764,7 +768,8 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup param([string]$resourceGroupName, [object]$azureRMVMResources, [string]$enableCopyPrerequisites, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) [hashtable]$fqdnMap = @{} $winRMHttpsPortMap = New-Object 'System.Collections.Generic.Dictionary[string, string]' @@ -788,13 +793,14 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup if (-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { - - if($isAzureStackEnvironment) + + if($isAzureStackEnvironment) { Write-Verbose "Fetching resource group resources details for Azure Stack environment." - $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetailsForAzureStack -resourceGroupName $resourceGroupName -azureRMVMResources $azureRMVMResources -endpoint $endpoint + $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetailsForAzureStack -resourceGroupName $resourceGroupName ` + -azureRMVMResources $azureRMVMResources -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken } - else + else { Write-Verbose "Fetching resource group resources details for Azure/National cloud environments." $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetails -resourceGroupName $resourceGroupName -azureRMVMResources $azureRMVMResources @@ -849,7 +855,8 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup if ($enableCopyPrerequisites -eq "true") { Write-Verbose "Enabling winrm for virtual machine $resourceName" -Verbose - Add-AzureVMCustomScriptExtension -resourceGroupName $resourceGroupName -vmId $resourceId -vmName $resourceName -dnsName $resourceFQDN -location $resource.Location -connectedServiceName $connectedServiceName + Add-AzureVMCustomScriptExtension -resourceGroupName $resourceGroupName -vmId $resourceId -vmName $resourceName -dnsName $resourceFQDN ` + -location $resource.Location -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken } } @@ -890,7 +897,8 @@ function Get-AzureVMResourcesProperties [string]$resourceFilteringMethod, [string]$machineNames, [string]$enableCopyPrerequisites, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $machineNames = $machineNames.Trim() if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($connectionType)) @@ -917,7 +925,8 @@ function Get-AzureVMResourcesProperties { $azureRMVMResources = Get-AzureRMVMsInResourceGroup -resourceGroupName $resourceGroupName $filteredAzureRMVMResources = Get-FilteredAzureRMVMsInResourceGroup -azureRMVMResources $azureRMVMResources -resourceFilteringMethod $resourceFilteringMethod -filter $machineNames - $azureVMsDetails = Get-AzureRMVMsConnectionDetailsInResourceGroup -resourceGroupName $resourceGroupName -azureRMVMResources $filteredAzureRMVMResources -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName + $azureVMsDetails = Get-AzureRMVMsConnectionDetailsInResourceGroup -resourceGroupName $resourceGroupName -azureRMVMResources $filteredAzureRMVMResources ` + -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken } # throw if no azure VMs found in resource group or due to filtering @@ -1141,9 +1150,11 @@ function Copy-FilesToAzureVMsFromStorageContainer function Validate-CustomScriptExecutionStatus { param([string]$resourceGroupName, - [string]$vmName, - [string]$extensionName, - [object]$endpoint) + [string]$vmName, + [string]$extensionName, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) Write-Verbose "Validating the winrm configuration custom script extension status" @@ -1183,18 +1194,19 @@ function Validate-CustomScriptExecutionStatus else { $isScriptExecutionPassed = $false - $errMessage = "No custom script extension '$extensionName' exists" + $errMessage = "No custom script extension '$extensionName' exists" } } catch { $isScriptExecutionPassed = $false - $errMessage = $_.Exception.Message + $errMessage = $_.Exception.Message } if(-not $isScriptExecutionPassed) { - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $endpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $endpoint -connectedServiceNameARM $connectedServiceNameARM -vstsAccessToken $vstsAccessToken throw (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionFailed" -ArgumentList $extensionName, $vmName, $errMessage) } @@ -1206,7 +1218,8 @@ function Is-WinRMCustomScriptExtensionExists param([string]$resourceGroupName, [string]$vmName, [string]$extensionName, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $isExtensionExists = $true $removeExtension = $false @@ -1214,13 +1227,14 @@ function Is-WinRMCustomScriptExtensionExists try { $serviceEndpoint=Get-Endpoint $connectedServiceName - $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken if($customScriptExtension) { if($customScriptExtension.ProvisioningState -ne "Succeeded") - { - $removeExtension = $true + { + $removeExtension = $true } else { @@ -1241,28 +1255,30 @@ function Is-WinRMCustomScriptExtensionExists } catch { - $isExtensionExists = $false + $isExtensionExists = $false } if($removeExtension) { - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken try { - $index = 1 + $index = 1 $maxCount = 45 # Setting timeout for deleting extension as 15 mins. while($index -le $maxCount) { Write-Verbose "Checking WinRM custom script extension status $index times" - $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken - if(-not $customScriptExtension -or $customScriptExtension.ProvisioningState -ne "deleting") + if(-not $customScriptExtension -or $customScriptExtension.ProvisioningState -ne "deleting") { break } - + start-sleep -s 20 $index = $index + 1 } @@ -1350,7 +1366,8 @@ function Add-AzureVMCustomScriptExtension [string]$vmName, [string]$dnsName, [string]$location, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $configWinRMScriptFileFwdLink ="https://aka.ms/vstsconfigurewinrm" $makeCertFileFwdLink ="https://aka.ms/vstsmakecertexe" @@ -1367,13 +1384,14 @@ function Add-AzureVMCustomScriptExtension try { $endpoint = Get-Endpoint $connectedServiceName - $isExtensionExists = Is-WinRMCustomScriptExtensionExists -resourceGroupName $resourceGroupName -vmName $vmName -extensionName $extensionName -connectedServiceName $connectedServiceName + $isExtensionExists = Is-WinRMCustomScriptExtensionExists -resourceGroupName $resourceGroupName -vmName $vmName -extensionName $extensionName ` + -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken Write-Verbose -Verbose "IsExtensionExists: $isExtensionExists" if($isExtensionExists) - { + { Add-WinRMHttpsNetworkSecurityRuleConfig -resourceGroupName $resourceGroupName -vmId $vmId -ruleName $ruleName -rulePriotity $rulePriotity -winrmHttpsPort $winrmHttpsPort - + Write-Verbose "Skipping the addition of custom script extension '$extensionName' as it already exists" return } @@ -1387,9 +1405,10 @@ function Add-AzureVMCustomScriptExtension if($result.Status -ne "Succeeded") { - Write-Telemetry "Task_InternalError" "ProvisionVmCustomScriptFailed" + Write-Telemetry "Task_InternalError" "ProvisionVmCustomScriptFailed" - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $endpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken throw (Get-VstsLocString -Key "AFC_UnableToSetCustomScriptExtension" -ArgumentList $extensionName, $vmName, $result.Error.Message) } diff --git a/Tasks/AzureFileCopyV3/AzureFileCopy.ps1 b/Tasks/AzureFileCopyV3/AzureFileCopy.ps1 index 5a064a0ea883..f3667355e4b7 100644 --- a/Tasks/AzureFileCopyV3/AzureFileCopy.ps1 +++ b/Tasks/AzureFileCopyV3/AzureFileCopy.ps1 @@ -64,10 +64,13 @@ Import-Module $PSScriptRoot\ps_modules\RemoteDeployer Import-Module $PSScriptRoot\ps_modules\VstsAzureHelpers_ $endpoint = Get-VstsEndpoint -Name $connectedServiceName -Require -if (Get-Module Az.Accounts -ListAvailable){ - Initialize-AzModule -Endpoint $endpoint +$vstsEndpoint = Get-VstsEndpoint -Name SystemVssConnection -Require +$vstsAccessToken = $vstsEndpoint.auth.parameters.AccessToken + +if (Get-Module Az.Accounts -ListAvailable) { + Initialize-AzModule -Endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken } -else{ +else { Update-PSModulePathForHostedAgentWithLatestModule -Endpoint $endpoint Initialize-AzureRMModule -Endpoint $endpoint } @@ -100,13 +103,13 @@ try { Write-Host "##vso[telemetry.publish area=TaskEndpointId;feature=AzureFileCopy]$telemetryJsonContent" # Getting storage key for the storage account - $storageKey = Get-StorageKey -storageAccountName $storageAccount -endpoint $endpoint + $storageKey = Get-StorageKey -storageAccountName $storageAccount -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken # creating storage context to be used while creating container, sas token, deleting container $storageContext = Create-AzureStorageContext -StorageAccountName $storageAccount -StorageAccountKey $storageKey - + # Geting Azure Storage Account type - $storageAccountType = Get-StorageAccountType -storageAccountName $storageAccount -endpoint $endpoint + $storageAccountType = Get-StorageAccountType $storageAccount $endpoint $connectedServiceName $vstsEndpoint Write-Verbose "Obtained Storage Account type: $storageAccountType" if(-not [string]::IsNullOrEmpty($storageAccountType) -and $storageAccountType.Contains('Premium')) { @@ -208,11 +211,12 @@ try { # Normalize admin username if($vmsAdminUserName -and (-not $vmsAdminUserName.StartsWith(".\")) -and ($vmsAdminUserName.IndexOf("\") -eq -1) -and ($vmsAdminUserName.IndexOf("@") -eq -1)) { - $vmsAdminUserName = ".\" + $vmsAdminUserName + $vmsAdminUserName = ".\" + $vmsAdminUserName } # getting azure vms properties(name, fqdn, winrmhttps port) $azureVMResourcesProperties = Get-AzureVMResourcesProperties -resourceGroupName $environmentName ` - -resourceFilteringMethod $resourceFilteringMethod -machineNames $machineNames -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName + -resourceFilteringMethod $resourceFilteringMethod -machineNames $machineNames -enableCopyPrerequisites $enableCopyPrerequisites ` + -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken $azureVMsCredentials = Get-AzureVMsCredentials -vmsAdminUserName $vmsAdminUserName -vmsAdminPassword $vmsAdminPassword diff --git a/Tasks/AzureFileCopyV3/AzureUtilityRest.ps1 b/Tasks/AzureFileCopyV3/AzureUtilityRest.ps1 index 02ab68144015..d1119903394a 100644 --- a/Tasks/AzureFileCopyV3/AzureUtilityRest.ps1 +++ b/Tasks/AzureFileCopyV3/AzureUtilityRest.ps1 @@ -3,7 +3,9 @@ Import-Module $PSScriptRoot\ps_modules\VstsAzureRestHelpers_ function Get-AzureStorageKeyFromARM { param([string]$storageAccountName, - [object]$serviceEndpoint) + [object]$serviceEndpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) if (-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -11,8 +13,8 @@ function Get-AzureStorageKeyFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage key for the storage account: $storageAccount in resource group: $azureResourceid" - - $storageKeyDetails = Get-AzRMStorageKeys $azureResourceGroupName $storageAccountName $serviceEndpoint + + $storageKeyDetails = Get-AzRMStorageKeys $azureResourceGroupName $storageAccountName $serviceEndpoint $connectedServiceNameARM $vstsAccessToken $storageKey = $storageKeyDetails.Key1 Write-Verbose "[Azure Call]Retrieved storage key successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -23,7 +25,9 @@ function Get-AzureStorageKeyFromARM function Get-AzureBlobStorageEndpointFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -31,19 +35,21 @@ function Get-AzureBlobStorageEndpointFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account endpoint for the storage account: $storageAccount in resource group: $azureResourceGroupName" - - $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint -ErrorAction Stop + + $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken -ErrorAction Stop $storageAccountEnpoint = $storageAccountInfo.PrimaryEndpoints[0].blob Write-Verbose "[Azure Call]Retrieved storage account endpoint successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" return $storageAccountEnpoint - } + } } function Get-AzureStorageAccountTypeFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -51,42 +57,46 @@ function Get-AzureStorageAccountTypeFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account type for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint -ErrorAction Stop + $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken -ErrorAction Stop $storageAccountType = $storageAccountInfo.sku.tier Write-Verbose "[Azure Call]Retrieved storage account type successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" return $storageAccountType - } + } } function Get-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName)) { Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtension" -ArgumentList $name, $vmName) - $customScriptExtension = Get-AzRmVmCustomScriptExtension $resourceGroupName $vmName $name $endpoint + $customScriptExtension = Get-AzRmVmCustomScriptExtension $resourceGroupName $vmName $name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } - + return $customScriptExtension } function Remove-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtension" -ArgumentList $name, $vmName) - $response = Remove-AzRmVMCustomScriptExtension $resourceGroupName $vmName $name $endpoint + $response = Remove-AzRmVMCustomScriptExtension $resourceGroupName $vmName $name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -96,26 +106,28 @@ function Remove-AzureMachineCustomScriptExtension function Get-AzureRMResourceGroupResourcesDetailsForAzureStack { param([string]$resourceGroupName, - [object]$azureRMVMResources, - [object]$endpoint) + [object]$azureRMVMResources, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) [hashtable]$azureRGResourcesDetails = @{} [hashtable]$loadBalancerDetails = @{} - + if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureNetworkInterfaceDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $networkInterfaceResources = Get-AzureNetworkInterfaceDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzurePublicIpAddressDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $publicIPAddressResources = Get-AzurePublicIpAddressDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureLoadBalancersDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $lbGroup = Get-AzureLoadBalancersDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -124,7 +136,7 @@ function Get-AzureRMResourceGroupResourcesDetailsForAzureStack { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureLoadBalancerDetails -Name $lb.Name -ResourceGroupName $resourceGroupName -endpoint $endpoint + $loadBalancer = Get-AzureLoadBalancerDetails $resourceGroupName $lb.Name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" diff --git a/Tasks/AzureFileCopyV3/Utility.ps1 b/Tasks/AzureFileCopyV3/Utility.ps1 index 6cd132598107..7b45170e5f46 100644 --- a/Tasks/AzureFileCopyV3/Utility.ps1 +++ b/Tasks/AzureFileCopyV3/Utility.ps1 @@ -59,7 +59,9 @@ function Validate-AzurePowershellVersion function Get-StorageKey { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [object][Parameter(Mandatory=$true)]$endpoint) + [object][Parameter(Mandatory=$true)]$endpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) $storageAccountName = $storageAccountName.Trim() @@ -67,7 +69,7 @@ function Get-StorageKey Validate-AzurePowershellVersion # getting storage account key from ARM endpoint - $storageKey = Get-AzureStorageKeyFromARM -storageAccountName $storageAccountName -serviceEndpoint $endpoint + $storageKey = Get-AzureStorageKeyFromARM -storageAccountName $storageAccountName -serviceEndpoint $endpoint $connectedServiceNameARM $vstsAccessToken return $storageKey } @@ -75,12 +77,14 @@ function Get-StorageKey function Get-blobStorageEndpoint { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [object][Parameter(Mandatory=$true)]$endpoint) + [object][Parameter(Mandatory=$true)]$endpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) $storageAccountName = $storageAccountName.Trim() # getting storage account key from ARM endpoint - $blobStorageEndpoint = Get-AzureBlobStorageEndpointFromARM -storageAccountName $storageAccountName -endpoint $endpoint + $blobStorageEndpoint = Get-AzureBlobStorageEndpointFromARM $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken return $blobStorageEndpoint } @@ -88,13 +92,15 @@ function Get-blobStorageEndpoint function Get-StorageAccountType { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [object][Parameter(Mandatory=$true)]$endpoint) + [object][Parameter(Mandatory=$true)]$endpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) $storageAccountName = $storageAccountName.Trim() # getting storage account type from ARM endpoint - $storageAccountType = Get-AzureStorageAccountTypeFromARM -storageAccountName $storageAccountName -endpoint $endpoint + $storageAccountType = Get-AzureStorageAccountTypeFromARM $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken - if($storageAccountType -ne $null) + if($null -ne $storageAccountType) { return $storageAccountType.ToString() } @@ -645,7 +651,8 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup param([string]$resourceGroupName, [object]$azureRMVMResources, [string]$enableCopyPrerequisites, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) [hashtable]$fqdnMap = @{} $winRMHttpsPortMap = New-Object 'System.Collections.Generic.Dictionary[string, string]' @@ -669,13 +676,14 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup if (-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { - - if($isAzureStackEnvironment) + + if($isAzureStackEnvironment) { Write-Verbose "Fetching resource group resources details for Azure Stack environment." - $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetailsForAzureStack -resourceGroupName $resourceGroupName -azureRMVMResources $azureRMVMResources -endpoint $endpoint + $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetailsForAzureStack -resourceGroupName $resourceGroupName ` + -azureRMVMResources $azureRMVMResources -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken } - else + else { Write-Verbose "Fetching resource group resources details for Azure/National cloud environments." $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetails -resourceGroupName $resourceGroupName -azureRMVMResources $azureRMVMResources @@ -730,7 +738,8 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup if ($enableCopyPrerequisites -eq "true") { Write-Verbose "Enabling winrm for virtual machine $resourceName" -Verbose - Add-AzureVMCustomScriptExtension -resourceGroupName $resourceGroupName -vmId $resourceId -vmName $resourceName -dnsName $resourceFQDN -location $resource.Location -connectedServiceName $connectedServiceName + Add-AzureVMCustomScriptExtension -resourceGroupName $resourceGroupName -vmId $resourceId -vmName $resourceName -dnsName $resourceFQDN ` + -location $resource.Location -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken } } @@ -744,14 +753,16 @@ function Get-AzureVMResourcesProperties [string]$resourceFilteringMethod, [string]$machineNames, [string]$enableCopyPrerequisites, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $machineNames = $machineNames.Trim() if(-not [string]::IsNullOrEmpty($resourceGroupName)) { $azureRMVMResources = Get-AzureRMVMsInResourceGroup -resourceGroupName $resourceGroupName $filteredAzureRMVMResources = Get-FilteredAzureRMVMsInResourceGroup -azureRMVMResources $azureRMVMResources -resourceFilteringMethod $resourceFilteringMethod -filter $machineNames - $azureVMsDetails = Get-AzureRMVMsConnectionDetailsInResourceGroup -resourceGroupName $resourceGroupName -azureRMVMResources $filteredAzureRMVMResources -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName + $azureVMsDetails = Get-AzureRMVMsConnectionDetailsInResourceGroup -resourceGroupName $resourceGroupName -azureRMVMResources $filteredAzureRMVMResources ` + -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken # throw if no azure VMs found in resource group or due to filtering if($azureVMsDetails.Count -eq 0) @@ -961,9 +972,11 @@ function Copy-FilesToAzureVMsFromStorageContainer function Validate-CustomScriptExecutionStatus { param([string]$resourceGroupName, - [string]$vmName, - [string]$extensionName, - [object]$endpoint) + [string]$vmName, + [string]$extensionName, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) Write-Verbose "Validating the winrm configuration custom script extension status" @@ -1003,18 +1016,19 @@ function Validate-CustomScriptExecutionStatus else { $isScriptExecutionPassed = $false - $errMessage = "No custom script extension '$extensionName' exists" + $errMessage = "No custom script extension '$extensionName' exists" } } catch { $isScriptExecutionPassed = $false - $errMessage = $_.Exception.Message + $errMessage = $_.Exception.Message } if(-not $isScriptExecutionPassed) { - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $endpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $endpoint -connectedServiceNameARM $connectedServiceNameARM -vstsAccessToken $vstsAccessToken throw (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionFailed" -ArgumentList $extensionName, $vmName, $errMessage) } @@ -1026,7 +1040,8 @@ function Is-WinRMCustomScriptExtensionExists param([string]$resourceGroupName, [string]$vmName, [string]$extensionName, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $isExtensionExists = $true $removeExtension = $false @@ -1034,13 +1049,14 @@ function Is-WinRMCustomScriptExtensionExists try { $serviceEndpoint=Get-Endpoint $connectedServiceName - $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken if($customScriptExtension) { if($customScriptExtension.ProvisioningState -ne "Succeeded") - { - $removeExtension = $true + { + $removeExtension = $true } else { @@ -1061,28 +1077,30 @@ function Is-WinRMCustomScriptExtensionExists } catch { - $isExtensionExists = $false + $isExtensionExists = $false } if($removeExtension) { - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken try { - $index = 1 + $index = 1 $maxCount = 45 # Setting timeout for deleting extension as 15 mins. while($index -le $maxCount) { Write-Verbose "Checking WinRM custom script extension status $index times" - $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken - if(-not $customScriptExtension -or $customScriptExtension.ProvisioningState -ne "deleting") + if(-not $customScriptExtension -or $customScriptExtension.ProvisioningState -ne "deleting") { break } - + start-sleep -s 20 $index = $index + 1 } @@ -1170,7 +1188,8 @@ function Add-AzureVMCustomScriptExtension [string]$vmName, [string]$dnsName, [string]$location, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $configWinRMScriptFileFwdLink ="https://aka.ms/vstsconfigurewinrm" $makeCertFileFwdLink ="https://aka.ms/vstsmakecertexe" @@ -1187,13 +1206,14 @@ function Add-AzureVMCustomScriptExtension try { $endpoint = Get-Endpoint $connectedServiceName - $isExtensionExists = Is-WinRMCustomScriptExtensionExists -resourceGroupName $resourceGroupName -vmName $vmName -extensionName $extensionName -connectedServiceName $connectedServiceName + $isExtensionExists = Is-WinRMCustomScriptExtensionExists -resourceGroupName $resourceGroupName -vmName $vmName -extensionName $extensionName ` + -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken Write-Verbose -Verbose "IsExtensionExists: $isExtensionExists" if($isExtensionExists) - { + { Add-WinRMHttpsNetworkSecurityRuleConfig -resourceGroupName $resourceGroupName -vmId $vmId -ruleName $ruleName -rulePriotity $rulePriotity -winrmHttpsPort $winrmHttpsPort - + Write-Verbose "Skipping the addition of custom script extension '$extensionName' as it already exists" return } @@ -1207,9 +1227,10 @@ function Add-AzureVMCustomScriptExtension if($result.Status -ne "Succeeded") { - Write-Telemetry "Task_InternalError" "ProvisionVmCustomScriptFailed" + Write-Telemetry "Task_InternalError" "ProvisionVmCustomScriptFailed" - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $endpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken throw (Get-VstsLocString -Key "AFC_UnableToSetCustomScriptExtension" -ArgumentList $extensionName, $vmName, $result.Error.Message) } diff --git a/Tasks/AzureFileCopyV4/AzureFileCopy.ps1 b/Tasks/AzureFileCopyV4/AzureFileCopy.ps1 index 61d0bf7c9889..784360d67dad 100644 --- a/Tasks/AzureFileCopyV4/AzureFileCopy.ps1 +++ b/Tasks/AzureFileCopyV4/AzureFileCopy.ps1 @@ -67,10 +67,13 @@ $endpoint = Get-VstsEndpoint -Name $connectedServiceName -Require . "$PSScriptRoot\Utility.ps1" CleanUp-PSModulePathForHostedAgent -if (Get-Module Az.Accounts -ListAvailable){ - Initialize-AzModule -Endpoint $endpoint +$vstsEndpoint = Get-VstsEndpoint -Name SystemVssConnection -Require +$vstsAccessToken = $vstsEndpoint.auth.parameters.AccessToken + +if (Get-Module Az.Accounts -ListAvailable) { + Initialize-AzModule -Endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken } -else{ +else { Initialize-AzureRMModule -Endpoint $endpoint } @@ -101,13 +104,13 @@ try { Write-Host "##vso[telemetry.publish area=TaskEndpointId;feature=AzureFileCopy]$telemetryJsonContent" # Getting storage key for the storage account - $storageKey = Get-StorageKey -storageAccountName $storageAccount -endpoint $endpoint + $storageKey = Get-StorageKey -storageAccountName $storageAccount -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken # creating storage context to be used while creating container, sas token, deleting container $storageContext = Create-AzureStorageContext -StorageAccountName $storageAccount -StorageAccountKey $storageKey - + # Geting Azure Storage Account type - $storageAccountType = Get-StorageAccountType -storageAccountName $storageAccount -endpoint $endpoint + $storageAccountType = Get-StorageAccountType $storageAccount $endpoint $connectedServiceName $vstsEndpoint Write-Verbose "Obtained Storage Account type: $storageAccountType" if(-not [string]::IsNullOrEmpty($storageAccountType) -and $storageAccountType.Contains('Premium')) { @@ -127,14 +130,14 @@ try { $containerPresent = Get-AzureContainer -containerName $containerName -storageContext $storageContext #creating container if the containerName provided does not exist - if($containerPresent -eq $null) + if($null -eq $containerPresent) { Write-Verbose "Creating container if the containerName provided does not exist" Create-AzureContainer -containerName $containerName -storageContext $storageContext } } - + # Getting Azure Blob Storage Endpoint $blobStorageEndpoint = Get-blobStorageEndpoint -storageAccountName $storageAccount -endpoint $endpoint @@ -213,11 +216,12 @@ try { # Normalize admin username if($vmsAdminUserName -and (-not $vmsAdminUserName.StartsWith(".\")) -and ($vmsAdminUserName.IndexOf("\") -eq -1) -and ($vmsAdminUserName.IndexOf("@") -eq -1)) { - $vmsAdminUserName = ".\" + $vmsAdminUserName + $vmsAdminUserName = ".\" + $vmsAdminUserName } # getting azure vms properties(name, fqdn, winrmhttps port) $azureVMResourcesProperties = Get-AzureVMResourcesProperties -resourceGroupName $environmentName ` - -resourceFilteringMethod $resourceFilteringMethod -machineNames $machineNames -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName + -resourceFilteringMethod $resourceFilteringMethod -machineNames $machineNames -enableCopyPrerequisites $enableCopyPrerequisites ` + -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken $azureVMsCredentials = Get-AzureVMsCredentials -vmsAdminUserName $vmsAdminUserName -vmsAdminPassword $vmsAdminPassword diff --git a/Tasks/AzureFileCopyV4/AzureUtilityRest.ps1 b/Tasks/AzureFileCopyV4/AzureUtilityRest.ps1 index 02ab68144015..d1119903394a 100644 --- a/Tasks/AzureFileCopyV4/AzureUtilityRest.ps1 +++ b/Tasks/AzureFileCopyV4/AzureUtilityRest.ps1 @@ -3,7 +3,9 @@ Import-Module $PSScriptRoot\ps_modules\VstsAzureRestHelpers_ function Get-AzureStorageKeyFromARM { param([string]$storageAccountName, - [object]$serviceEndpoint) + [object]$serviceEndpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) if (-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -11,8 +13,8 @@ function Get-AzureStorageKeyFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage key for the storage account: $storageAccount in resource group: $azureResourceid" - - $storageKeyDetails = Get-AzRMStorageKeys $azureResourceGroupName $storageAccountName $serviceEndpoint + + $storageKeyDetails = Get-AzRMStorageKeys $azureResourceGroupName $storageAccountName $serviceEndpoint $connectedServiceNameARM $vstsAccessToken $storageKey = $storageKeyDetails.Key1 Write-Verbose "[Azure Call]Retrieved storage key successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -23,7 +25,9 @@ function Get-AzureStorageKeyFromARM function Get-AzureBlobStorageEndpointFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -31,19 +35,21 @@ function Get-AzureBlobStorageEndpointFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account endpoint for the storage account: $storageAccount in resource group: $azureResourceGroupName" - - $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint -ErrorAction Stop + + $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken -ErrorAction Stop $storageAccountEnpoint = $storageAccountInfo.PrimaryEndpoints[0].blob Write-Verbose "[Azure Call]Retrieved storage account endpoint successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" return $storageAccountEnpoint - } + } } function Get-AzureStorageAccountTypeFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -51,42 +57,46 @@ function Get-AzureStorageAccountTypeFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account type for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint -ErrorAction Stop + $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken -ErrorAction Stop $storageAccountType = $storageAccountInfo.sku.tier Write-Verbose "[Azure Call]Retrieved storage account type successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" return $storageAccountType - } + } } function Get-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName)) { Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtension" -ArgumentList $name, $vmName) - $customScriptExtension = Get-AzRmVmCustomScriptExtension $resourceGroupName $vmName $name $endpoint + $customScriptExtension = Get-AzRmVmCustomScriptExtension $resourceGroupName $vmName $name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } - + return $customScriptExtension } function Remove-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtension" -ArgumentList $name, $vmName) - $response = Remove-AzRmVMCustomScriptExtension $resourceGroupName $vmName $name $endpoint + $response = Remove-AzRmVMCustomScriptExtension $resourceGroupName $vmName $name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -96,26 +106,28 @@ function Remove-AzureMachineCustomScriptExtension function Get-AzureRMResourceGroupResourcesDetailsForAzureStack { param([string]$resourceGroupName, - [object]$azureRMVMResources, - [object]$endpoint) + [object]$azureRMVMResources, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) [hashtable]$azureRGResourcesDetails = @{} [hashtable]$loadBalancerDetails = @{} - + if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureNetworkInterfaceDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $networkInterfaceResources = Get-AzureNetworkInterfaceDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzurePublicIpAddressDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $publicIPAddressResources = Get-AzurePublicIpAddressDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureLoadBalancersDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $lbGroup = Get-AzureLoadBalancersDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -124,7 +136,7 @@ function Get-AzureRMResourceGroupResourcesDetailsForAzureStack { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureLoadBalancerDetails -Name $lb.Name -ResourceGroupName $resourceGroupName -endpoint $endpoint + $loadBalancer = Get-AzureLoadBalancerDetails $resourceGroupName $lb.Name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" diff --git a/Tasks/AzureFileCopyV4/Utility.ps1 b/Tasks/AzureFileCopyV4/Utility.ps1 index 9673f8fa9f97..ce565bee8360 100644 --- a/Tasks/AzureFileCopyV4/Utility.ps1 +++ b/Tasks/AzureFileCopyV4/Utility.ps1 @@ -59,7 +59,9 @@ function Validate-AzurePowershellVersion function Get-StorageKey { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [object][Parameter(Mandatory=$true)]$endpoint) + [object][Parameter(Mandatory=$true)]$endpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) $storageAccountName = $storageAccountName.Trim() @@ -67,7 +69,7 @@ function Get-StorageKey Validate-AzurePowershellVersion # getting storage account key from ARM endpoint - $storageKey = Get-AzureStorageKeyFromARM -storageAccountName $storageAccountName -serviceEndpoint $endpoint + $storageKey = Get-AzureStorageKeyFromARM -storageAccountName $storageAccountName -serviceEndpoint $endpoint $connectedServiceNameARM $vstsAccessToken return $storageKey } @@ -75,12 +77,14 @@ function Get-StorageKey function Get-blobStorageEndpoint { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [object][Parameter(Mandatory=$true)]$endpoint) + [object][Parameter(Mandatory=$true)]$endpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) $storageAccountName = $storageAccountName.Trim() # getting storage account key from ARM endpoint - $blobStorageEndpoint = Get-AzureBlobStorageEndpointFromARM -storageAccountName $storageAccountName -endpoint $endpoint + $blobStorageEndpoint = Get-AzureBlobStorageEndpointFromARM $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken return $blobStorageEndpoint } @@ -88,13 +92,15 @@ function Get-blobStorageEndpoint function Get-StorageAccountType { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [object][Parameter(Mandatory=$true)]$endpoint) + [object][Parameter(Mandatory=$true)]$endpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) $storageAccountName = $storageAccountName.Trim() # getting storage account type from ARM endpoint - $storageAccountType = Get-AzureStorageAccountTypeFromARM -storageAccountName $storageAccountName -endpoint $endpoint + $storageAccountType = Get-AzureStorageAccountTypeFromARM $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken - if($storageAccountType -ne $null) + if($null -ne $storageAccountType) { return $storageAccountType.ToString() } @@ -695,7 +701,8 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup param([string]$resourceGroupName, [object]$azureRMVMResources, [string]$enableCopyPrerequisites, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) [hashtable]$fqdnMap = @{} $winRMHttpsPortMap = New-Object 'System.Collections.Generic.Dictionary[string, string]' @@ -719,13 +726,14 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup if (-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { - - if($isAzureStackEnvironment) + + if($isAzureStackEnvironment) { Write-Verbose "Fetching resource group resources details for Azure Stack environment." - $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetailsForAzureStack -resourceGroupName $resourceGroupName -azureRMVMResources $azureRMVMResources -endpoint $endpoint + $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetailsForAzureStack -resourceGroupName $resourceGroupName ` + -azureRMVMResources $azureRMVMResources -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken } - else + else { Write-Verbose "Fetching resource group resources details for Azure/National cloud environments." $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetails -resourceGroupName $resourceGroupName -azureRMVMResources $azureRMVMResources @@ -780,7 +788,8 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup if ($enableCopyPrerequisites -eq "true") { Write-Verbose "Enabling winrm for virtual machine $resourceName" -Verbose - Add-AzureVMCustomScriptExtension -resourceGroupName $resourceGroupName -vmId $resourceId -vmName $resourceName -dnsName $resourceFQDN -location $resource.Location -connectedServiceName $connectedServiceName + Add-AzureVMCustomScriptExtension -resourceGroupName $resourceGroupName -vmId $resourceId -vmName $resourceName -dnsName $resourceFQDN ` + -location $resource.Location -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken } } @@ -794,14 +803,16 @@ function Get-AzureVMResourcesProperties [string]$resourceFilteringMethod, [string]$machineNames, [string]$enableCopyPrerequisites, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $machineNames = $machineNames.Trim() if(-not [string]::IsNullOrEmpty($resourceGroupName)) { $azureRMVMResources = Get-AzureRMVMsInResourceGroup -resourceGroupName $resourceGroupName $filteredAzureRMVMResources = Get-FilteredAzureRMVMsInResourceGroup -azureRMVMResources $azureRMVMResources -resourceFilteringMethod $resourceFilteringMethod -filter $machineNames - $azureVMsDetails = Get-AzureRMVMsConnectionDetailsInResourceGroup -resourceGroupName $resourceGroupName -azureRMVMResources $filteredAzureRMVMResources -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName + $azureVMsDetails = Get-AzureRMVMsConnectionDetailsInResourceGroup -resourceGroupName $resourceGroupName -azureRMVMResources $filteredAzureRMVMResources ` + -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken # throw if no azure VMs found in resource group or due to filtering if($azureVMsDetails.Count -eq 0) @@ -1008,9 +1019,11 @@ function Copy-FilesToAzureVMsFromStorageContainer function Validate-CustomScriptExecutionStatus { param([string]$resourceGroupName, - [string]$vmName, - [string]$extensionName, - [object]$endpoint) + [string]$vmName, + [string]$extensionName, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) Write-Verbose "Validating the winrm configuration custom script extension status" @@ -1050,18 +1063,19 @@ function Validate-CustomScriptExecutionStatus else { $isScriptExecutionPassed = $false - $errMessage = "No custom script extension '$extensionName' exists" + $errMessage = "No custom script extension '$extensionName' exists" } } catch { $isScriptExecutionPassed = $false - $errMessage = $_.Exception.Message + $errMessage = $_.Exception.Message } if(-not $isScriptExecutionPassed) { - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $endpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $endpoint -connectedServiceNameARM $connectedServiceNameARM -vstsAccessToken $vstsAccessToken throw (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionFailed" -ArgumentList $extensionName, $vmName, $errMessage) } @@ -1073,7 +1087,8 @@ function Is-WinRMCustomScriptExtensionExists param([string]$resourceGroupName, [string]$vmName, [string]$extensionName, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $isExtensionExists = $true $removeExtension = $false @@ -1081,13 +1096,14 @@ function Is-WinRMCustomScriptExtensionExists try { $serviceEndpoint=Get-Endpoint $connectedServiceName - $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken if($customScriptExtension) { if($customScriptExtension.ProvisioningState -ne "Succeeded") - { - $removeExtension = $true + { + $removeExtension = $true } else { @@ -1108,28 +1124,30 @@ function Is-WinRMCustomScriptExtensionExists } catch { - $isExtensionExists = $false + $isExtensionExists = $false } if($removeExtension) { - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken try { - $index = 1 + $index = 1 $maxCount = 45 # Setting timeout for deleting extension as 15 mins. while($index -le $maxCount) { Write-Verbose "Checking WinRM custom script extension status $index times" - $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken - if(-not $customScriptExtension -or $customScriptExtension.ProvisioningState -ne "deleting") + if(-not $customScriptExtension -or $customScriptExtension.ProvisioningState -ne "deleting") { break } - + start-sleep -s 20 $index = $index + 1 } @@ -1217,7 +1235,8 @@ function Add-AzureVMCustomScriptExtension [string]$vmName, [string]$dnsName, [string]$location, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $configWinRMScriptFileFwdLink ="https://aka.ms/vstsconfigurewinrm" $makeCertFileFwdLink ="https://aka.ms/vstsmakecertexe" @@ -1234,13 +1253,14 @@ function Add-AzureVMCustomScriptExtension try { $endpoint = Get-Endpoint $connectedServiceName - $isExtensionExists = Is-WinRMCustomScriptExtensionExists -resourceGroupName $resourceGroupName -vmName $vmName -extensionName $extensionName -connectedServiceName $connectedServiceName + $isExtensionExists = Is-WinRMCustomScriptExtensionExists -resourceGroupName $resourceGroupName -vmName $vmName -extensionName $extensionName ` + -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken Write-Verbose -Verbose "IsExtensionExists: $isExtensionExists" if($isExtensionExists) - { + { Add-WinRMHttpsNetworkSecurityRuleConfig -resourceGroupName $resourceGroupName -vmId $vmId -ruleName $ruleName -rulePriotity $rulePriotity -winrmHttpsPort $winrmHttpsPort - + Write-Verbose "Skipping the addition of custom script extension '$extensionName' as it already exists" return } @@ -1254,9 +1274,10 @@ function Add-AzureVMCustomScriptExtension if($result.Status -ne "Succeeded") { - Write-Telemetry "Task_InternalError" "ProvisionVmCustomScriptFailed" + Write-Telemetry "Task_InternalError" "ProvisionVmCustomScriptFailed" - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $endpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken throw (Get-VstsLocString -Key "AFC_UnableToSetCustomScriptExtension" -ArgumentList $extensionName, $vmName, $result.Error.Message) } diff --git a/Tasks/AzureFileCopyV5/AzureFileCopy.ps1 b/Tasks/AzureFileCopyV5/AzureFileCopy.ps1 index 3f4b736b41f6..a77b81aa69da 100644 --- a/Tasks/AzureFileCopyV5/AzureFileCopy.ps1 +++ b/Tasks/AzureFileCopyV5/AzureFileCopy.ps1 @@ -67,12 +67,15 @@ $endpoint = Get-VstsEndpoint -Name $connectedServiceName -Require . "$PSScriptRoot\Utility.ps1" CleanUp-PSModulePathForHostedAgent -if (Get-Module Az.Accounts -ListAvailable){ - Initialize-AzModule -Endpoint $endpoint +$vstsEndpoint = Get-VstsEndpoint -Name SystemVssConnection -Require +$vstsAccessToken = $vstsEndpoint.auth.parameters.AccessToken + +if (Get-Module Az.Accounts -ListAvailable) { + Initialize-AzModule -Endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken } -else{ +else { Write-Verbose "No module found with name: Az.Accounts" - throw ("Could not find the module Az.Accounts with given version. If the module was recently installed, retry after restarting the Azure Pipelines task agent.") + throw ("Could not find the module Az.Accounts with given version. If the module was recently installed, retry after restarting the Azure Pipelines task agent.") } # Import the loc strings. @@ -102,13 +105,13 @@ try { Write-Host "##vso[telemetry.publish area=TaskEndpointId;feature=AzureFileCopy]$telemetryJsonContent" # Getting storage key for the storage account - $storageKey = Get-StorageKey -storageAccountName $storageAccount -endpoint $endpoint + $storageKey = Get-StorageKey -storageAccountName $storageAccount -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken # creating storage context to be used while creating container, sas token, deleting container $storageContext = Create-AzureStorageContext -StorageAccountName $storageAccount -StorageAccountKey $storageKey - + # Geting Azure Storage Account type - $storageAccountType = Get-StorageAccountType -storageAccountName $storageAccount -endpoint $endpoint + $storageAccountType = Get-StorageAccountType $storageAccount $endpoint $connectedServiceName $vstsAccessToken Write-Verbose "Obtained Storage Account type: $storageAccountType" if(-not [string]::IsNullOrEmpty($storageAccountType) -and $storageAccountType.Contains('Premium')) { @@ -128,14 +131,14 @@ try { $containerPresent = Get-AzureContainer -containerName $containerName -storageContext $storageContext #creating container if the containerName provided does not exist - if($containerPresent -eq $null) + if($null -eq $containerPresent) { Write-Verbose "Creating container if the containerName provided does not exist" Create-AzureContainer -containerName $containerName -storageContext $storageContext } } - + # Getting Azure Blob Storage Endpoint $blobStorageEndpoint = Get-blobStorageEndpoint -storageAccountName $storageAccount -endpoint $endpoint @@ -215,11 +218,12 @@ try { # Normalize admin username if($vmsAdminUserName -and (-not $vmsAdminUserName.StartsWith(".\")) -and ($vmsAdminUserName.IndexOf("\") -eq -1) -and ($vmsAdminUserName.IndexOf("@") -eq -1)) { - $vmsAdminUserName = ".\" + $vmsAdminUserName + $vmsAdminUserName = ".\" + $vmsAdminUserName } # getting azure vms properties(name, fqdn, winrmhttps port) $azureVMResourcesProperties = Get-AzureVMResourcesProperties -resourceGroupName $environmentName ` - -resourceFilteringMethod $resourceFilteringMethod -machineNames $machineNames -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName + -resourceFilteringMethod $resourceFilteringMethod -machineNames $machineNames -enableCopyPrerequisites $enableCopyPrerequisites ` + -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken $azureVMsCredentials = Get-AzureVMsCredentials -vmsAdminUserName $vmsAdminUserName -vmsAdminPassword $vmsAdminPassword diff --git a/Tasks/AzureFileCopyV5/AzureUtilityRest.ps1 b/Tasks/AzureFileCopyV5/AzureUtilityRest.ps1 index 02ab68144015..d1119903394a 100644 --- a/Tasks/AzureFileCopyV5/AzureUtilityRest.ps1 +++ b/Tasks/AzureFileCopyV5/AzureUtilityRest.ps1 @@ -3,7 +3,9 @@ Import-Module $PSScriptRoot\ps_modules\VstsAzureRestHelpers_ function Get-AzureStorageKeyFromARM { param([string]$storageAccountName, - [object]$serviceEndpoint) + [object]$serviceEndpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) if (-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -11,8 +13,8 @@ function Get-AzureStorageKeyFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage key for the storage account: $storageAccount in resource group: $azureResourceid" - - $storageKeyDetails = Get-AzRMStorageKeys $azureResourceGroupName $storageAccountName $serviceEndpoint + + $storageKeyDetails = Get-AzRMStorageKeys $azureResourceGroupName $storageAccountName $serviceEndpoint $connectedServiceNameARM $vstsAccessToken $storageKey = $storageKeyDetails.Key1 Write-Verbose "[Azure Call]Retrieved storage key successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -23,7 +25,9 @@ function Get-AzureStorageKeyFromARM function Get-AzureBlobStorageEndpointFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -31,19 +35,21 @@ function Get-AzureBlobStorageEndpointFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account endpoint for the storage account: $storageAccount in resource group: $azureResourceGroupName" - - $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint -ErrorAction Stop + + $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken -ErrorAction Stop $storageAccountEnpoint = $storageAccountInfo.PrimaryEndpoints[0].blob Write-Verbose "[Azure Call]Retrieved storage account endpoint successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" return $storageAccountEnpoint - } + } } function Get-AzureStorageAccountTypeFromARM { param([string]$storageAccountName, - [object]$endpoint) + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($storageAccountName)) { @@ -51,42 +57,46 @@ function Get-AzureStorageAccountTypeFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account type for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint -ErrorAction Stop + $storageAccountInfo = Get-AzRMStorageAccount $azureResourceGroupName $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken -ErrorAction Stop $storageAccountType = $storageAccountInfo.sku.tier Write-Verbose "[Azure Call]Retrieved storage account type successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" return $storageAccountType - } + } } function Get-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName)) { Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtension" -ArgumentList $name, $vmName) - $customScriptExtension = Get-AzRmVmCustomScriptExtension $resourceGroupName $vmName $name $endpoint + $customScriptExtension = Get-AzRmVmCustomScriptExtension $resourceGroupName $vmName $name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } - + return $customScriptExtension } function Remove-AzureMachineCustomScriptExtension { param([string]$resourceGroupName, - [string]$vmName, - [string]$name, - [object]$endpoint) + [string]$vmName, + [string]$name, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtension" -ArgumentList $name, $vmName) - $response = Remove-AzRmVMCustomScriptExtension $resourceGroupName $vmName $name $endpoint + $response = Remove-AzRmVMCustomScriptExtension $resourceGroupName $vmName $name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -96,26 +106,28 @@ function Remove-AzureMachineCustomScriptExtension function Get-AzureRMResourceGroupResourcesDetailsForAzureStack { param([string]$resourceGroupName, - [object]$azureRMVMResources, - [object]$endpoint) + [object]$azureRMVMResources, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) [hashtable]$azureRGResourcesDetails = @{} [hashtable]$loadBalancerDetails = @{} - + if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureNetworkInterfaceDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $networkInterfaceResources = Get-AzureNetworkInterfaceDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzurePublicIpAddressDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $publicIPAddressResources = Get-AzurePublicIpAddressDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureLoadBalancersDetails -ResourceGroupName $resourceGroupName -endpoint $endpoint + $lbGroup = Get-AzureLoadBalancersDetails $resourceGroupName $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -124,7 +136,7 @@ function Get-AzureRMResourceGroupResourcesDetailsForAzureStack { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureLoadBalancerDetails -Name $lb.Name -ResourceGroupName $resourceGroupName -endpoint $endpoint + $loadBalancer = Get-AzureLoadBalancerDetails $resourceGroupName $lb.Name $endpoint $connectedServiceNameARM $vstsAccessToken Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" diff --git a/Tasks/AzureFileCopyV5/Utility.ps1 b/Tasks/AzureFileCopyV5/Utility.ps1 index a375575095cd..495623b40fbb 100644 --- a/Tasks/AzureFileCopyV5/Utility.ps1 +++ b/Tasks/AzureFileCopyV5/Utility.ps1 @@ -59,7 +59,9 @@ function Validate-AzurePowershellVersion function Get-StorageKey { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [object][Parameter(Mandatory=$true)]$endpoint) + [object][Parameter(Mandatory=$true)]$endpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) $storageAccountName = $storageAccountName.Trim() @@ -67,7 +69,7 @@ function Get-StorageKey Validate-AzurePowershellVersion # getting storage account key from ARM endpoint - $storageKey = Get-AzureStorageKeyFromARM -storageAccountName $storageAccountName -serviceEndpoint $endpoint + $storageKey = Get-AzureStorageKeyFromARM -storageAccountName $storageAccountName -serviceEndpoint $endpoint $connectedServiceNameARM $vstsAccessToken return $storageKey } @@ -75,12 +77,14 @@ function Get-StorageKey function Get-blobStorageEndpoint { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [object][Parameter(Mandatory=$true)]$endpoint) + [object][Parameter(Mandatory=$true)]$endpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) $storageAccountName = $storageAccountName.Trim() # getting storage account key from ARM endpoint - $blobStorageEndpoint = Get-AzureBlobStorageEndpointFromARM -storageAccountName $storageAccountName -endpoint $endpoint + $blobStorageEndpoint = Get-AzureBlobStorageEndpointFromARM $storageAccountName $endpoint $connectedServiceNameARM $vstsAccessToken return $blobStorageEndpoint } @@ -88,13 +92,15 @@ function Get-blobStorageEndpoint function Get-StorageAccountType { param([string][Parameter(Mandatory=$true)]$storageAccountName, - [object][Parameter(Mandatory=$true)]$endpoint) + [object][Parameter(Mandatory=$true)]$endpoint, + [string][Parameter(Mandatory=$false)]$connectedServiceNameARM, + [string][Parameter(Mandatory=$false)]$vstsAccessToken) $storageAccountName = $storageAccountName.Trim() # getting storage account type from ARM endpoint - $storageAccountType = Get-AzureStorageAccountTypeFromARM -storageAccountName $storageAccountName -endpoint $endpoint + $storageAccountType = Get-AzureStorageAccountTypeFromARM $storageAccountName $endpoint $connectedServiceNameARM $vsstsAccessToken - if($storageAccountType -ne $null) + if($null -ne $storageAccountType) { return $storageAccountType.ToString() } @@ -708,7 +714,8 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup param([string]$resourceGroupName, [object]$azureRMVMResources, [string]$enableCopyPrerequisites, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) [hashtable]$fqdnMap = @{} $winRMHttpsPortMap = New-Object 'System.Collections.Generic.Dictionary[string, string]' @@ -732,13 +739,14 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup if (-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { - - if($isAzureStackEnvironment) + + if($isAzureStackEnvironment) { Write-Verbose "Fetching resource group resources details for Azure Stack environment." - $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetailsForAzureStack -resourceGroupName $resourceGroupName -azureRMVMResources $azureRMVMResources -endpoint $endpoint + $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetailsForAzureStack -resourceGroupName $resourceGroupName ` + -azureRMVMResources $azureRMVMResources -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken } - else + else { Write-Verbose "Fetching resource group resources details for Azure/National cloud environments." $azureRGResourcesDetails = Get-AzureRMResourceGroupResourcesDetails -resourceGroupName $resourceGroupName -azureRMVMResources $azureRMVMResources @@ -793,7 +801,8 @@ function Get-AzureRMVMsConnectionDetailsInResourceGroup if ($enableCopyPrerequisites -eq "true") { Write-Verbose "Enabling winrm for virtual machine $resourceName" -Verbose - Add-AzureVMCustomScriptExtension -resourceGroupName $resourceGroupName -vmId $resourceId -vmName $resourceName -dnsName $resourceFQDN -location $resource.Location -connectedServiceName $connectedServiceName + Add-AzureVMCustomScriptExtension -resourceGroupName $resourceGroupName -vmId $resourceId -vmName $resourceName -dnsName $resourceFQDN ` + -location $resource.Location -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken } } @@ -807,14 +816,16 @@ function Get-AzureVMResourcesProperties [string]$resourceFilteringMethod, [string]$machineNames, [string]$enableCopyPrerequisites, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $machineNames = $machineNames.Trim() if(-not [string]::IsNullOrEmpty($resourceGroupName)) { $azureRMVMResources = Get-AzureRMVMsInResourceGroup -resourceGroupName $resourceGroupName $filteredAzureRMVMResources = Get-FilteredAzureRMVMsInResourceGroup -azureRMVMResources $azureRMVMResources -resourceFilteringMethod $resourceFilteringMethod -filter $machineNames - $azureVMsDetails = Get-AzureRMVMsConnectionDetailsInResourceGroup -resourceGroupName $resourceGroupName -azureRMVMResources $filteredAzureRMVMResources -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName + $azureVMsDetails = Get-AzureRMVMsConnectionDetailsInResourceGroup -resourceGroupName $resourceGroupName -azureRMVMResources $filteredAzureRMVMResources ` + -enableCopyPrerequisites $enableCopyPrerequisites -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken # throw if no azure VMs found in resource group or due to filtering if($azureVMsDetails.Count -eq 0) @@ -1021,9 +1032,11 @@ function Copy-FilesToAzureVMsFromStorageContainer function Validate-CustomScriptExecutionStatus { param([string]$resourceGroupName, - [string]$vmName, - [string]$extensionName, - [object]$endpoint) + [string]$vmName, + [string]$extensionName, + [object]$endpoint, + [string]$connectedServiceNameARM, + [string]$vstsAccessToken) Write-Verbose "Validating the winrm configuration custom script extension status" @@ -1063,18 +1076,19 @@ function Validate-CustomScriptExecutionStatus else { $isScriptExecutionPassed = $false - $errMessage = "No custom script extension '$extensionName' exists" + $errMessage = "No custom script extension '$extensionName' exists" } } catch { $isScriptExecutionPassed = $false - $errMessage = $_.Exception.Message + $errMessage = $_.Exception.Message } if(-not $isScriptExecutionPassed) { - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $endpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $endpoint -connectedServiceNameARM $connectedServiceNameARM -vstsAccessToken $vstsAccessToken throw (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionFailed" -ArgumentList $extensionName, $vmName, $errMessage) } @@ -1086,21 +1100,23 @@ function Is-WinRMCustomScriptExtensionExists param([string]$resourceGroupName, [string]$vmName, [string]$extensionName, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $isExtensionExists = $true $removeExtension = $false try { - $serviceEndpoint=Get-Endpoint $connectedServiceName - $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $serviceEndpoint = Get-Endpoint $connectedServiceName + $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken if($customScriptExtension) { if($customScriptExtension.ProvisioningState -ne "Succeeded") - { - $removeExtension = $true + { + $removeExtension = $true } else { @@ -1121,28 +1137,30 @@ function Is-WinRMCustomScriptExtensionExists } catch { - $isExtensionExists = $false + $isExtensionExists = $false } if($removeExtension) { - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken try { - $index = 1 + $index = 1 $maxCount = 45 # Setting timeout for deleting extension as 15 mins. while($index -le $maxCount) { Write-Verbose "Checking WinRM custom script extension status $index times" - $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $serviceEndpoint + $customScriptExtension = Get-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $serviceEndpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken - if(-not $customScriptExtension -or $customScriptExtension.ProvisioningState -ne "deleting") + if(-not $customScriptExtension -or $customScriptExtension.ProvisioningState -ne "deleting") { break } - + start-sleep -s 20 $index = $index + 1 } @@ -1230,7 +1248,8 @@ function Add-AzureVMCustomScriptExtension [string]$vmName, [string]$dnsName, [string]$location, - [string]$connectedServiceName) + [string]$connectedServiceName, + [string]$vstsAccessToken) $configWinRMScriptFileFwdLink ="https://aka.ms/vstsconfigurewinrm" $makeCertFileFwdLink ="https://aka.ms/vstsmakecertexe" @@ -1247,13 +1266,14 @@ function Add-AzureVMCustomScriptExtension try { $endpoint = Get-Endpoint $connectedServiceName - $isExtensionExists = Is-WinRMCustomScriptExtensionExists -resourceGroupName $resourceGroupName -vmName $vmName -extensionName $extensionName -connectedServiceName $connectedServiceName + $isExtensionExists = Is-WinRMCustomScriptExtensionExists -resourceGroupName $resourceGroupName -vmName $vmName -extensionName $extensionName ` + -connectedServiceName $connectedServiceName -vstsAccessToken $vstsAccessToken Write-Verbose -Verbose "IsExtensionExists: $isExtensionExists" if($isExtensionExists) - { + { Add-WinRMHttpsNetworkSecurityRuleConfig -resourceGroupName $resourceGroupName -vmId $vmId -ruleName $ruleName -rulePriotity $rulePriotity -winrmHttpsPort $winrmHttpsPort - + Write-Verbose "Skipping the addition of custom script extension '$extensionName' as it already exists" return } @@ -1267,9 +1287,10 @@ function Add-AzureVMCustomScriptExtension if($result.Status -ne "Succeeded") { - Write-Telemetry "Task_InternalError" "ProvisionVmCustomScriptFailed" + Write-Telemetry "Task_InternalError" "ProvisionVmCustomScriptFailed" - $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName -endpoint $endpoint + $response = Remove-AzureMachineCustomScriptExtension -resourceGroupName $resourceGroupName -vmName $vmName -name $extensionName ` + -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken throw (Get-VstsLocString -Key "AFC_UnableToSetCustomScriptExtension" -ArgumentList $extensionName, $vmName, $result.Error.Message) } diff --git a/Tasks/AzurePowerShellV2/AzurePowerShell.ps1 b/Tasks/AzurePowerShellV2/AzurePowerShell.ps1 index 0381260cc131..3813d3d2d3da 100644 --- a/Tasks/AzurePowerShellV2/AzurePowerShell.ps1 +++ b/Tasks/AzurePowerShellV2/AzurePowerShell.ps1 @@ -77,7 +77,14 @@ Update-PSModulePathForHostedAgent -targetAzurePs $targetAzurePs -authScheme $aut try { # Initialize Azure. Import-Module $PSScriptRoot\ps_modules\VstsAzureHelpers_ - Initialize-Azure -azurePsVersion $targetAzurePs + if (($authScheme -eq 'WorkloadIdentityFederation') -and (Get-Module Az.Accounts -ListAvailable)) { + $vstsEndpoint = Get-VstsEndpoint -Name SystemVssConnection -Require + $vstsAccessToken = $vstsEndpoint.auth.parameters.AccessToken + Initialize-AzModule -Endpoint $endpoint -connectedServiceNameARM $serviceName -vstsAccessToken $vstsAccessToken + } + else { + Initialize-Azure -azurePsVersion $targetAzurePs + } # Trace the expression as it will be invoked. $__vstsAzPSInlineScriptPath = $null If ($scriptType -eq "InlineScript") { diff --git a/Tasks/AzurePowerShellV2/Utility.ps1 b/Tasks/AzurePowerShellV2/Utility.ps1 index 6e06f57f6fdc..ef7d21e5ea1c 100644 --- a/Tasks/AzurePowerShellV2/Utility.ps1 +++ b/Tasks/AzurePowerShellV2/Utility.ps1 @@ -30,25 +30,33 @@ function Update-PSModulePathForHostedAgent { $hostedAgentAzureModulePath = Get-SavedModulePath -azurePowerShellVersion $targetAzurePs -Classic } else { - $hostedAgentAzureRmModulePath = Get-LatestModule -patternToMatch "^azurerm_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" -Classic:$false - $hostedAgentAzureModulePath = Get-LatestModule -patternToMatch "^azure_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" -Classic:$true + $hostedAgentAzureRmModulePath = Get-LatestModule -patternToMatch "^azurerm_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" -moduleName:'AzureRM' + $hostedAgentAzureModulePath = Get-LatestModule -patternToMatch "^azure_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" -moduleName:'Azure' } - if($authScheme -eq 'ServicePrincipal' -or $authScheme -eq '') - { + if ($authScheme -eq 'ServicePrincipal' -or $authScheme -eq '') { $env:PSModulePath = $hostedAgentAzureModulePath + ";" + $env:PSModulePath $env:PSModulePath = $env:PSModulePath.TrimStart(';') $env:PSModulePath = $hostedAgentAzureRmModulePath + ";" + $env:PSModulePath $env:PSModulePath = $env:PSModulePath.TrimStart(';') } - else - { + elseif ($authScheme -eq 'WorkloadIdentityFederation') { + if ($targetAzurePs) { + $hostedAgentAzureAzModulePath = (Get-SavedModuleContainerPath) + "\az_" + $targetAzurePs + } + else { + $hostedAgentAzureAzModulePath = Get-LatestModule -patternToMatch "^az_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" -moduleName:'Az' + } + $env:PSModulePath = $hostedAgentAzureAzModulePath + ";" + $env:PSModulePath + $env:PSModulePath = $env:PSModulePath.TrimStart(';') + } + else { $env:PSModulePath = $hostedAgentAzureRmModulePath + ";" + $env:PSModulePath $env:PSModulePath = $env:PSModulePath.TrimStart(';') $env:PSModulePath = $hostedAgentAzureModulePath + ";" + $env:PSModulePath $env:PSModulePath = $env:PSModulePath.TrimStart(';') } - + } finally { Write-Verbose "The updated value of the PSModulePath is: $($env:PSModulePath)" Trace-VstsLeavingInvocation $MyInvocation @@ -59,8 +67,8 @@ function Get-LatestModule { [CmdletBinding()] param([string] $patternToMatch, [string] $patternToExtract, - [switch] $Classic) - + [string] $moduleName) + $resultFolder = "" $regexToMatch = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $patternToMatch $regexToExtract = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $patternToExtract @@ -71,11 +79,7 @@ function Get-LatestModule { foreach ($moduleFolder in $moduleFolders) { $moduleVersion = [version] $($regexToExtract.Match($moduleFolder.Name).Groups[0].Value) if($moduleVersion -gt $maxVersion) { - if($Classic) { - $modulePath = [System.IO.Path]::Combine($moduleFolder.FullName,"Azure\$moduleVersion\Azure.psm1") - } else { - $modulePath = [System.IO.Path]::Combine($moduleFolder.FullName,"AzureRM\$moduleVersion\AzureRM.psm1") - } + $modulePath = [System.IO.Path]::Combine($moduleFolder.FullName,"$moduleName\$moduleVersion\$moduleName.psm1") if(Test-Path -LiteralPath $modulePath -PathType Leaf) { $maxVersion = $moduleVersion diff --git a/Tasks/AzurePowerShellV2/task.json b/Tasks/AzurePowerShellV2/task.json index 027066d22f98..f93df9367a84 100644 --- a/Tasks/AzurePowerShellV2/task.json +++ b/Tasks/AzurePowerShellV2/task.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 218, - "Patch": 0 + "Minor": 221, + "Patch": 100 }, "demands": [ "azureps" diff --git a/Tasks/AzurePowerShellV2/task.loc.json b/Tasks/AzurePowerShellV2/task.loc.json index 4888cecc37b6..54d6c4aa0093 100644 --- a/Tasks/AzurePowerShellV2/task.loc.json +++ b/Tasks/AzurePowerShellV2/task.loc.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 218, - "Patch": 0 + "Minor": 221, + "Patch": 100 }, "demands": [ "azureps" diff --git a/Tasks/AzurePowerShellV3/AzurePowerShell.ps1 b/Tasks/AzurePowerShellV3/AzurePowerShell.ps1 index dc80a115bfee..71724b7b5e59 100644 --- a/Tasks/AzurePowerShellV3/AzurePowerShell.ps1 +++ b/Tasks/AzurePowerShellV3/AzurePowerShell.ps1 @@ -110,10 +110,17 @@ $troubleshoot = "https://aka.ms/azurepowershelltroubleshooting" try { # Initialize Azure. Import-Module $PSScriptRoot\ps_modules\VstsAzureHelpers_ - Initialize-Azure -azurePsVersion $targetAzurePs -strict + if (($authScheme -eq 'WorkloadIdentityFederation') -and (Get-Module Az.Accounts -ListAvailable)) { + $vstsEndpoint = Get-VstsEndpoint -Name SystemVssConnection -Require + $vstsAccessToken = $vstsEndpoint.auth.parameters.AccessToken + Initialize-AzModule -Endpoint $endpoint -connectedServiceNameARM $serviceName -vstsAccessToken $vstsAccessToken + } + else { + Initialize-Azure -azurePsVersion $targetAzurePs -strict + } Write-Host "## Initializing Azure Complete" $success = $true -} +} finally { if (!$success) { Write-VstsTaskError "Initialize Azure failed: For troubleshooting, refer: $troubleshoot" diff --git a/Tasks/AzurePowerShellV3/Utility.ps1 b/Tasks/AzurePowerShellV3/Utility.ps1 index 2fbe61c21710..63f4eef7e165 100644 --- a/Tasks/AzurePowerShellV3/Utility.ps1 +++ b/Tasks/AzurePowerShellV3/Utility.ps1 @@ -30,25 +30,33 @@ function Update-PSModulePathForHostedAgent { $hostedAgentAzureModulePath = Get-SavedModulePath -azurePowerShellVersion $targetAzurePs -Classic } else { - $hostedAgentAzureRmModulePath = Get-LatestModule -patternToMatch "^azurerm_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" -Classic:$false - $hostedAgentAzureModulePath = Get-LatestModule -patternToMatch "^azure_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" -Classic:$true + $hostedAgentAzureRmModulePath = Get-LatestModule -patternToMatch "^azurerm_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" -moduleName:'AzureRM' + $hostedAgentAzureModulePath = Get-LatestModule -patternToMatch "^azure_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" -moduleName:'Azure' } - if($authScheme -eq 'ServicePrincipal' -or $authScheme -eq 'ManagedServiceIdentity' -or $authScheme -eq '') - { + if ($authScheme -eq 'ServicePrincipal' -or $authScheme -eq 'ManagedServiceIdentity' -or $authScheme -eq '') { $env:PSModulePath = $hostedAgentAzureModulePath + ";" + $env:PSModulePath $env:PSModulePath = $env:PSModulePath.TrimStart(';') $env:PSModulePath = $hostedAgentAzureRmModulePath + ";" + $env:PSModulePath $env:PSModulePath = $env:PSModulePath.TrimStart(';') } - else - { + elseif ($authScheme -eq 'WorkloadIdentityFederation') { + if ($targetAzurePs) { + $hostedAgentAzureAzModulePath = (Get-SavedModuleContainerPath) + "\az_" + $targetAzurePs + } + else { + $hostedAgentAzureAzModulePath = Get-LatestModule -patternToMatch "^az_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" -moduleName:'Az' + } + $env:PSModulePath = $hostedAgentAzureAzModulePath + ";" + $env:PSModulePath + $env:PSModulePath = $env:PSModulePath.TrimStart(';') + } + else { $env:PSModulePath = $hostedAgentAzureRmModulePath + ";" + $env:PSModulePath $env:PSModulePath = $env:PSModulePath.TrimStart(';') $env:PSModulePath = $hostedAgentAzureModulePath + ";" + $env:PSModulePath $env:PSModulePath = $env:PSModulePath.TrimStart(';') } - + } finally { Write-Verbose "The updated value of the PSModulePath is: $($env:PSModulePath)" Trace-VstsLeavingInvocation $MyInvocation @@ -59,8 +67,8 @@ function Get-LatestModule { [CmdletBinding()] param([string] $patternToMatch, [string] $patternToExtract, - [switch] $Classic) - + [string] $moduleName) + $resultFolder = "" $regexToMatch = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $patternToMatch $regexToExtract = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $patternToExtract @@ -71,11 +79,7 @@ function Get-LatestModule { foreach ($moduleFolder in $moduleFolders) { $moduleVersion = [version] $($regexToExtract.Match($moduleFolder.Name).Groups[0].Value) if($moduleVersion -gt $maxVersion) { - if($Classic) { - $modulePath = [System.IO.Path]::Combine($moduleFolder.FullName,"Azure\$moduleVersion\Azure.psm1") - } else { - $modulePath = [System.IO.Path]::Combine($moduleFolder.FullName,"AzureRM\$moduleVersion\AzureRM.psm1") - } + $modulePath = [System.IO.Path]::Combine($moduleFolder.FullName,"$moduleName\$moduleVersion\$moduleName.psm1") if(Test-Path -LiteralPath $modulePath -PathType Leaf) { $maxVersion = $moduleVersion diff --git a/Tasks/AzurePowerShellV3/task.json b/Tasks/AzurePowerShellV3/task.json index 9b808a697b84..e821911c8a42 100644 --- a/Tasks/AzurePowerShellV3/task.json +++ b/Tasks/AzurePowerShellV3/task.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 3, - "Minor": 220, - "Patch": 0 + "Minor": 221, + "Patch": 100 }, "releaseNotes": "Added support for Fail on standard error and ErrorActionPreference", "demands": [ diff --git a/Tasks/AzurePowerShellV3/task.loc.json b/Tasks/AzurePowerShellV3/task.loc.json index 1d7516063562..e84bf218ae35 100644 --- a/Tasks/AzurePowerShellV3/task.loc.json +++ b/Tasks/AzurePowerShellV3/task.loc.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 3, - "Minor": 220, - "Patch": 0 + "Minor": 221, + "Patch": 100 }, "releaseNotes": "ms-resource:loc.releaseNotes", "demands": [ diff --git a/Tasks/AzurePowerShellV4/AzurePowerShell.ps1 b/Tasks/AzurePowerShellV4/AzurePowerShell.ps1 index 5d74f6c1579d..a55c68ea25b8 100644 --- a/Tasks/AzurePowerShellV4/AzurePowerShell.ps1 +++ b/Tasks/AzurePowerShellV4/AzurePowerShell.ps1 @@ -83,14 +83,17 @@ $serviceName = Get-VstsInput -Name ConnectedServiceNameARM -Require $endpoint = Get-VstsEndpoint -Name $serviceName -Require CleanUp-PSModulePathForHostedAgent Update-PSModulePathForHostedAgent -targetAzurePs $targetAzurePs +$vstsEndpoint = Get-VstsEndpoint -Name SystemVssConnection -Require +$vstsAccessToken = $vstsEndpoint.auth.parameters.AccessToken # troubleshoot link $troubleshoot = "https://aka.ms/azurepowershelltroubleshooting" -try +try { # Initialize Azure. Import-Module $PSScriptRoot\ps_modules\VstsAzureHelpers_ - Initialize-AzModule -Endpoint $endpoint -azVersion $targetAzurePs + Initialize-AzModule -Endpoint $endpoint -connectedServiceNameARM $serviceName ` + -azVersion $targetAzurePs -vstsAccessToken $vstsAccessToken Write-Host "## Az module initialization Complete" $success = $true } diff --git a/Tasks/AzurePowerShellV4/task.json b/Tasks/AzurePowerShellV4/task.json index 57a9ae471dd2..34167f1f1d0d 100644 --- a/Tasks/AzurePowerShellV4/task.json +++ b/Tasks/AzurePowerShellV4/task.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 4, - "Minor": 220, - "Patch": 0 + "Minor": 221, + "Patch": 100 }, "releaseNotes": "Added support for Az Module and cross platform agents.", "groups": [ diff --git a/Tasks/AzurePowerShellV4/task.loc.json b/Tasks/AzurePowerShellV4/task.loc.json index 77e50bd35c58..730b3c28fc85 100644 --- a/Tasks/AzurePowerShellV4/task.loc.json +++ b/Tasks/AzurePowerShellV4/task.loc.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 4, - "Minor": 220, - "Patch": 0 + "Minor": 221, + "Patch": 100 }, "releaseNotes": "ms-resource:loc.releaseNotes", "groups": [ diff --git a/Tasks/AzurePowerShellV5/AzurePowerShell.ps1 b/Tasks/AzurePowerShellV5/AzurePowerShell.ps1 index a560d2725780..20e4a8a4df06 100644 --- a/Tasks/AzurePowerShellV5/AzurePowerShell.ps1 +++ b/Tasks/AzurePowerShellV5/AzurePowerShell.ps1 @@ -78,8 +78,10 @@ if ($validateScriptSignature) { $serviceName = Get-VstsInput -Name ConnectedServiceNameARM -Require $endpointObject = Get-VstsEndpoint -Name $serviceName -Require $endpoint = ConvertTo-Json $endpointObject +$vstsEndpoint = Get-VstsEndpoint -Name SystemVssConnection -Require +$vstsAccessToken = $vstsEndpoint.auth.parameters.AccessToken -try +try { # Generate the script contents. Write-Host (Get-VstsLocString -Key 'GeneratingScript') @@ -91,9 +93,9 @@ try $CoreAzArgument = $null; if ($targetAzurePs) { - $CoreAzArgument = "-endpoint '$endpoint' -targetAzurePs $targetAzurePs" + $CoreAzArgument = "-endpoint '$endpoint' -connectedServiceNameARM $serviceName -targetAzurePs $targetAzurePs -vstsAccessToken $vstsAccessToken" } else { - $CoreAzArgument = "-endpoint '$endpoint'" + $CoreAzArgument = "-endpoint '$endpoint' -connectedServiceNameARM $serviceName -vstsAccessToken $vstsAccessToken" } $contents += ". '$PSScriptRoot\CoreAz.ps1' $CoreAzArgument" diff --git a/Tasks/AzurePowerShellV5/CoreAz.ps1 b/Tasks/AzurePowerShellV5/CoreAz.ps1 index fdc17a75904a..e34820c1881e 100644 --- a/Tasks/AzurePowerShellV5/CoreAz.ps1 +++ b/Tasks/AzurePowerShellV5/CoreAz.ps1 @@ -5,7 +5,13 @@ param $endpoint, [String] [Parameter(Mandatory = $false)] - $targetAzurePs + $connectedServiceNameARM, + + [String] [Parameter(Mandatory = $false)] + $targetAzurePs, + + [String] [Parameter(Mandatory = $false)] + $vstsAccessToken ) Import-Module "$PSScriptRoot\ps_modules\VstsTaskSdk" -ArgumentList @{ NonInteractive = $true } @@ -18,4 +24,5 @@ Update-PSModulePathForHostedAgent -targetAzurePs $targetAzurePs $endpointObject = ConvertFrom-Json $endpoint Import-Module "$PSScriptRoot\ps_modules\VstsAzureHelpers_" -Initialize-AzModule -Endpoint $endpointObject -azVersion $targetAzurePs \ No newline at end of file +Initialize-AzModule -Endpoint $endpointObject -connectedServiceNameARM $connectedServiceNameARM ` + -azVersion $targetAzurePs -vstsAccessToken $vstsAccessToken \ No newline at end of file diff --git a/Tasks/AzurePowerShellV5/package-lock.json b/Tasks/AzurePowerShellV5/package-lock.json index a9cff27fbea3..82311d048ba1 100644 --- a/Tasks/AzurePowerShellV5/package-lock.json +++ b/Tasks/AzurePowerShellV5/package-lock.json @@ -1,782 +1,782 @@ { - "name": "azure-powershell-v5", - "requires": true, - "lockfileVersion": 1, - "dependencies": { - "@azure/msal-common": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-9.1.1.tgz", - "integrity": "sha512-we9xR8lvu47fF0h+J8KyXoRy9+G/fPzm3QEa2TrdR3jaVS3LKAyE2qyMuUkNdbVkvzl8Zr9f7l+IUSP22HeqXw==" - }, - "@azure/msal-node": { - "version": "1.14.5", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.14.5.tgz", - "integrity": "sha512-NcVdMfn8Z3ogN+9RjOSF7uwf2Gki5DEJl0BdDSL83KUAgVAobtkZi5W8EqxbJLrTO/ET0jv5DregrcR5qg2pEA==", - "requires": { - "@azure/msal-common": "^9.0.1", - "jsonwebtoken": "^8.5.1", - "uuid": "^8.3.0" - }, - "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - } - } - }, - "@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "requires": { - "@types/node": "*" - } - }, - "@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", - "requires": { - "@types/node": "*" - } - }, - "@types/jsonwebtoken": { - "version": "8.5.9", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz", - "integrity": "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==", - "requires": { - "@types/node": "*" - } - }, - "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" - }, - "@types/node": { - "version": "10.17.50", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.50.tgz", - "integrity": "sha512-vwX+/ija9xKc/z9VqMCdbf4WYcMTGsI0I/L/6shIF3qXURxZOhPQlPRHtjTpiNhAwn0paMJzlOQqw6mAGEQnTA==" - }, - "@types/q": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.0.7.tgz", - "integrity": "sha512-0WS7XU7sXzQ7J1nbnMKKYdjrrFoO3YtZYgUzeV8JFXffPnHfvSJQleR70I8BOAsOm14i4dyaAZ3YzqIl1YhkXQ==" - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "@types/semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" - }, - "@types/uuid": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.10.tgz", - "integrity": "sha512-BgeaZuElf7DEYZhWYDTc/XcLZXdVgFkVSTa13BqKvbnmUrxr3TJFKofUxCtDO9UQOdhnV+HPOESdHiHKZOJV1A==" - }, - "agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "async-mutex": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", - "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", - "requires": { - "tslib": "^2.4.0" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "azure-pipelines-task-lib": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-3.1.10.tgz", - "integrity": "sha512-S5iH1mD9G7boOV0kjVsFkqlz/6FOZjQAajshj3ajzQK9Wr3XRq9JK9+grJP4ityG6of28X2XWpieFdJLhnWLoA==", - "requires": { - "minimatch": "3.0.4", - "mockery": "^1.7.0", - "q": "^1.5.1", - "semver": "^5.1.0", - "shelljs": "^0.8.4", - "sync-request": "6.1.0", - "uuid": "^3.0.1" - } - }, - "azure-pipelines-tasks-azure-arm-rest-v2": { - "version": "3.217.1", - "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-azure-arm-rest-v2/-/azure-pipelines-tasks-azure-arm-rest-v2-3.217.1.tgz", - "integrity": "sha512-kozIoKwH8T85PaTyCoRBAGgw6UONPE3mswyoPGd9pN6hqH/dwpuuazG4QdW7DIePuivKg9UYNZn9qwJzdhTUtQ==", - "requires": { - "@azure/msal-node": "1.14.5", - "@types/jsonwebtoken": "^8.5.8", - "@types/mocha": "^5.2.7", - "@types/node": "^10.17.0", - "@types/q": "1.5.4", - "async-mutex": "^0.4.0", - "azure-pipelines-task-lib": "^3.1.0", - "https-proxy-agent": "^4.0.0", - "jsonwebtoken": "^8.5.1", - "node-fetch": "^2.6.7", - "q": "1.5.1", - "typed-rest-client": "1.8.4" - }, - "dependencies": { + "name": "azure-powershell-v5", + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@azure/msal-common": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-9.1.1.tgz", + "integrity": "sha512-we9xR8lvu47fF0h+J8KyXoRy9+G/fPzm3QEa2TrdR3jaVS3LKAyE2qyMuUkNdbVkvzl8Zr9f7l+IUSP22HeqXw==" + }, + "@azure/msal-node": { + "version": "1.14.5", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.14.5.tgz", + "integrity": "sha512-NcVdMfn8Z3ogN+9RjOSF7uwf2Gki5DEJl0BdDSL83KUAgVAobtkZi5W8EqxbJLrTO/ET0jv5DregrcR5qg2pEA==", + "requires": { + "@azure/msal-common": "^9.0.1", + "jsonwebtoken": "^8.5.1", + "uuid": "^8.3.0" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } + }, + "@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=", + "requires": { + "@types/node": "*" + } + }, + "@types/jsonwebtoken": { + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz", + "integrity": "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==", + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" + }, + "@types/node": { + "version": "10.17.50", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.50.tgz", + "integrity": "sha512-vwX+/ija9xKc/z9VqMCdbf4WYcMTGsI0I/L/6shIF3qXURxZOhPQlPRHtjTpiNhAwn0paMJzlOQqw6mAGEQnTA==" + }, "@types/q": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", - "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" - } - } - }, - "azure-pipelines-tasks-utility-common": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-utility-common/-/azure-pipelines-tasks-utility-common-3.0.3.tgz", - "integrity": "sha512-kG2RWtfYf3t+y0I+yJACRLOB1rJYjUf2dLlxwXqgOrAU1g2amVNTLbEcL/VSqqrFQq2UwvBoVVppDbwPyfhm9Q==", - "requires": { - "@types/node": "^10.17.0", - "azure-pipelines-task-lib": "^3.1.0", - "azure-pipelines-tool-lib": "^1.0.2", - "js-yaml": "3.13.1", - "semver": "^5.4.1" - } - }, - "azure-pipelines-tool-lib": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/azure-pipelines-tool-lib/-/azure-pipelines-tool-lib-1.0.2.tgz", - "integrity": "sha512-0wWAqIY1n9UvcHP3AKLWIVd5fTPKaUOZJ50bNwW3NMpFlfpxZDAi8Ck9wvVm9oBdwHVYZsQy3WfK71DiBWQiHg==", - "requires": { - "@types/semver": "^5.3.0", - "@types/uuid": "^3.4.5", - "azure-pipelines-task-lib": "^3.1.0", - "semver": "^5.7.0", - "semver-compare": "^1.0.0", - "typed-rest-client": "^1.8.4", - "uuid": "^3.3.2" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=" - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.0.7.tgz", + "integrity": "sha512-0WS7XU7sXzQ7J1nbnMKKYdjrrFoO3YtZYgUzeV8JFXffPnHfvSJQleR70I8BOAsOm14i4dyaAZ3YzqIl1YhkXQ==" + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "@types/semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" + }, + "@types/uuid": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.10.tgz", + "integrity": "sha512-BgeaZuElf7DEYZhWYDTc/XcLZXdVgFkVSTa13BqKvbnmUrxr3TJFKofUxCtDO9UQOdhnV+HPOESdHiHKZOJV1A==" + }, + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "async-mutex": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", + "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", + "requires": { + "tslib": "^2.4.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "azure-pipelines-task-lib": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-3.1.10.tgz", + "integrity": "sha512-S5iH1mD9G7boOV0kjVsFkqlz/6FOZjQAajshj3ajzQK9Wr3XRq9JK9+grJP4ityG6of28X2XWpieFdJLhnWLoA==", + "requires": { + "minimatch": "3.0.4", + "mockery": "^1.7.0", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.4", + "sync-request": "6.1.0", + "uuid": "^3.0.1" + } + }, + "azure-pipelines-tasks-azure-arm-rest-v2": { + "version": "3.217.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-azure-arm-rest-v2/-/azure-pipelines-tasks-azure-arm-rest-v2-3.217.1.tgz", + "integrity": "sha512-kozIoKwH8T85PaTyCoRBAGgw6UONPE3mswyoPGd9pN6hqH/dwpuuazG4QdW7DIePuivKg9UYNZn9qwJzdhTUtQ==", + "requires": { + "@azure/msal-node": "1.14.5", + "@types/jsonwebtoken": "^8.5.8", + "@types/mocha": "^5.2.7", + "@types/node": "^10.17.0", + "@types/q": "1.5.4", + "async-mutex": "^0.4.0", + "azure-pipelines-task-lib": "^3.1.0", + "https-proxy-agent": "^4.0.0", + "jsonwebtoken": "^8.5.1", + "node-fetch": "^2.6.7", + "q": "1.5.1", + "typed-rest-client": "1.8.4" + }, + "dependencies": { + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" + } + } + }, + "azure-pipelines-tasks-utility-common": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-utility-common/-/azure-pipelines-tasks-utility-common-3.0.3.tgz", + "integrity": "sha512-kG2RWtfYf3t+y0I+yJACRLOB1rJYjUf2dLlxwXqgOrAU1g2amVNTLbEcL/VSqqrFQq2UwvBoVVppDbwPyfhm9Q==", + "requires": { + "@types/node": "^10.17.0", + "azure-pipelines-task-lib": "^3.1.0", + "azure-pipelines-tool-lib": "^1.0.2", + "js-yaml": "3.13.1", + "semver": "^5.4.1" + } + }, + "azure-pipelines-tool-lib": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/azure-pipelines-tool-lib/-/azure-pipelines-tool-lib-1.0.2.tgz", + "integrity": "sha512-0wWAqIY1n9UvcHP3AKLWIVd5fTPKaUOZJ50bNwW3NMpFlfpxZDAi8Ck9wvVm9oBdwHVYZsQy3WfK71DiBWQiHg==", + "requires": { + "@types/semver": "^5.3.0", + "@types/uuid": "^3.4.5", + "azure-pipelines-task-lib": "^3.1.0", + "semver": "^5.7.0", + "semver-compare": "^1.0.0", + "typed-rest-client": "^1.8.4", + "uuid": "^3.3.2" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=" + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "requires": { + "@types/node": "^10.0.3" + } + }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "requires": { + "agent-base": "5", + "debug": "4" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "requires": { + "has": "^1.0.3" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + }, + "mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "requires": { + "mime-db": "1.51.0" + } + }, "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "requires": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - } - }, - "http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "requires": { - "@types/node": "^10.0.3" - } - }, - "https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", - "requires": { - "agent-base": "5", - "debug": "4" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" - }, - "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", - "requires": { - "has": "^1.0.3" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", - "requires": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^5.6.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" - }, - "lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" - }, - "lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" - }, - "lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" - }, - "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" - }, - "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "requires": { - "mime-db": "1.51.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mockery": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/mockery/-/mockery-1.7.0.tgz", - "integrity": "sha1-9O3g2HUMHJcnwnLqLGBiniyaHE8=" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node-fetch": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.8.tgz", - "integrity": "sha512-RZ6dBYuj8dRSfxpUSu+NsdF1dpPpluJxwOp+6IoDp/sH2QNDSvurYsAa+F1WxY2RjA1iP93xhcsUoYbF2XBqVg==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { - "wrappy": "1" - } - }, - "parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", - "requires": { - "asap": "~2.0.6" - } - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "requires": { - "resolve": "^1.1.6" - } - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" - }, - "shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, - "sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "requires": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - } - }, - "sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "requires": { - "get-port": "^3.1.0" - } - }, - "then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "requires": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "dependencies": { - "@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mockery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/mockery/-/mockery-1.7.0.tgz", + "integrity": "sha1-9O3g2HUMHJcnwnLqLGBiniyaHE8=" + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node-fetch": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.8.tgz", + "integrity": "sha512-RZ6dBYuj8dRSfxpUSu+NsdF1dpPpluJxwOp+6IoDp/sH2QNDSvurYsAa+F1WxY2RjA1iP93xhcsUoYbF2XBqVg==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "requires": { + "asap": "~2.0.6" + } + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + }, + "qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "requires": { + "resolve": "^1.1.6" + } + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "requires": { + "get-port": "^3.1.0" + } + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" + } + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, + "typed-rest-client": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.4.tgz", + "integrity": "sha512-MyfKKYzk3I6/QQp6e1T50py4qg+c+9BzOEl2rBmQIpStwNUoqQ73An+Tkfy9YuV7O+o2mpVVJpe+fH//POZkbg==", + "requires": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "typescript": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", + "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", + "dev": true + }, + "underscore": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", + "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" } - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" - }, - "tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" - }, - "typed-rest-client": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.4.tgz", - "integrity": "sha512-MyfKKYzk3I6/QQp6e1T50py4qg+c+9BzOEl2rBmQIpStwNUoqQ73An+Tkfy9YuV7O+o2mpVVJpe+fH//POZkbg==", - "requires": { - "qs": "^6.9.1", - "tunnel": "0.0.6", - "underscore": "^1.12.1" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "typescript": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", - "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", - "dev": true - }, - "underscore": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", - "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" } - } } diff --git a/Tasks/AzurePowerShellV5/task.json b/Tasks/AzurePowerShellV5/task.json index 4829347f8b71..7c28e6341840 100644 --- a/Tasks/AzurePowerShellV5/task.json +++ b/Tasks/AzurePowerShellV5/task.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 5, - "Minor": 220, - "Patch": 0 + "Minor": 221, + "Patch": 100 }, "releaseNotes": "Added support for Az Module and cross platform agents.", "groups": [ diff --git a/Tasks/AzurePowerShellV5/task.loc.json b/Tasks/AzurePowerShellV5/task.loc.json index 50e8d302c6e0..104f7f1745cf 100644 --- a/Tasks/AzurePowerShellV5/task.loc.json +++ b/Tasks/AzurePowerShellV5/task.loc.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 5, - "Minor": 220, - "Patch": 0 + "Minor": 221, + "Patch": 100 }, "releaseNotes": "ms-resource:loc.releaseNotes", "groups": [ diff --git a/Tasks/Common/VstsAzureHelpers_/ImportFunctions.ps1 b/Tasks/Common/VstsAzureHelpers_/ImportFunctions.ps1 index c77451f11f86..963716bc0180 100644 --- a/Tasks/Common/VstsAzureHelpers_/ImportFunctions.ps1 +++ b/Tasks/Common/VstsAzureHelpers_/ImportFunctions.ps1 @@ -84,8 +84,8 @@ function Import-FromModulePath { } # Attempt to resolve the module. - Write-Verbose "Attempting to find the module '$name' from the module path." if ($azurePsVersion) { + Write-Verbose "Attempting to find the module '$name' from the module path for version '$azurePsVersion'." $module = Get-Module -Name $name -ListAvailable | Where-Object {$_.Version -eq $azurePsVersion} | Select-Object -First 1 if (!$module) { Write-Verbose "No module found with name: $name, version: $azurePsVersion" @@ -93,6 +93,7 @@ function Import-FromModulePath { } } else { + Write-Verbose "Attempting to find the module '$name' from the module path for latest available version" $module = Get-Module -Name $name -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1 $sdkVersion = Get-SdkVersion if ((!$module) -or ($sdkVersion -and ($module.Version -lt [version]$sdkVersion))) { diff --git a/Tasks/Common/VstsAzureHelpers_/InitializeAzModuleFunctions.ps1 b/Tasks/Common/VstsAzureHelpers_/InitializeAzModuleFunctions.ps1 index d4438e9e4064..76e9d0ac5f47 100644 --- a/Tasks/Common/VstsAzureHelpers_/InitializeAzModuleFunctions.ps1 +++ b/Tasks/Common/VstsAzureHelpers_/InitializeAzModuleFunctions.ps1 @@ -6,15 +6,22 @@ function Initialize-AzModule { param( [Parameter(Mandatory=$true)] $Endpoint, - [string] $azVersion) + [Parameter(Mandatory=$false)] + [string] $connectedServiceNameARM, + [Parameter(Mandatory=$false)] + [string] $azVersion, + [Parameter(Mandatory=$false)] + [string]$vstsAccessToken) Trace-VstsEnteringInvocation $MyInvocation try { Write-Verbose "Env:PSModulePath: '$env:PSMODULEPATH'" - Import-AzModule -azVersion $azVersion + + $encryptedToken = ConvertTo-SecureString $vstsAccessToken -AsPlainText -Force + Initialize-AzSubscription -Endpoint $Endpoint -connectedServiceNameARM $connectedServiceNameARM -vstsAccessToken $encryptedToken Write-Verbose "Initializing Az Module." - Initialize-AzSubscription -Endpoint $Endpoint + Import-AzModule -azVersion $azVersion } finally { Trace-VstsLeavingInvocation $MyInvocation } @@ -30,7 +37,7 @@ function Import-AzModule { $moduleName = "Az.Accounts" # Attempt to resolve the module. Write-Verbose "Attempting to find the module '$moduleName' from the module path." - + if($azVersion -eq ""){ $module = Get-Module -Name $moduleName -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1 } @@ -41,13 +48,13 @@ function Import-AzModule { $azModulePath = Split-Path (Split-Path (Split-Path $moduleVal.Path -Parent) -Parent) -Parent $azModulePath = $azModulePath + "\Az\*" $azModuleVersion = split-path -path $azModulePath -Leaf -Resolve - if($azModuleVersion -eq $azVersion) { + if ($azModuleVersion -eq $azVersion) { $module = $moduleVal break - } + } } } - + if (!$module) { Write-Verbose "No module found with name: $moduleName" throw (Get-VstsLocString -Key AZ_ModuleNotFound -ArgumentList $azVersion, "Az.Accounts") @@ -57,49 +64,44 @@ function Import-AzModule { Write-Host "##[command]Import-Module -Name $($module.Path) -Global" $module = Import-Module -Name $module.Path -Global -PassThru -Force Write-Verbose "Imported module version: $($module.Version)" - } finally { + } finally { Trace-VstsLeavingInvocation $MyInvocation - } + } } function Initialize-AzSubscription { [CmdletBinding()] param( [Parameter(Mandatory=$true)] - $Endpoint) + $Endpoint, + [Parameter(Mandatory=$false)] + [string] $connectedServiceNameARM, + [Parameter(Mandatory=$false)] + [Security.SecureString]$vstsAccessToken) #Set UserAgent for Azure Calls Set-UserAgent - - # Clear context - Write-Host "##[command]Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue" - $null = Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue - Write-Host "##[command]Clear-AzContext -Scope Process" - $null = Clear-AzContext -Scope Process $environmentName = "AzureCloud" - if($Endpoint.Data.Environment) { + if ($Endpoint.Data.Environment) { $environmentName = $Endpoint.Data.Environment - if($environmentName -eq "AzureStack") - { + if($environmentName -eq "AzureStack") { Add-AzureStackAzEnvironment -endpoint $Endpoint -name "AzureStack" } } - - $scopeLevel = "Subscription" - $processScope = @{ Scope = "Process" } - - If ($Endpoint.PSObject.Properties['Data']) + $scopeLevel = "Subscription" + If (($Endpoint.PSObject.Properties['Data']) -and ($Endpoint.Data.PSObject.Properties['scopeLevel'])) { - If ($Endpoint.Data.PSObject.Properties['scopeLevel']) - { - $scopeLevel = $Endpoint.Data.scopeLevel - } + $scopeLevel = $Endpoint.Data.scopeLevel } if ($Endpoint.Auth.Scheme -eq 'ServicePrincipal') { try { + Write-Host "##[command]Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue" + $null = Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue + Write-Host "##[command]Clear-AzContext -Scope Process" + $null = Clear-AzContext -Scope Process if ($Endpoint.Auth.Parameters.AuthenticationType -eq 'SPNCertificate') { $servicePrincipalCertificate = Add-CertificateForAz -Endpoint $Endpoint @@ -123,35 +125,62 @@ function Initialize-AzSubscription { Credential=$psCredential; Environment=$environmentName; ServicePrincipal=$true; - } + } } - } + } catch { # Provide an additional, custom, credentials-related error message. Write-VstsTaskError -Message $_.Exception.Message Assert-TlsError -exception $_.Exception throw (New-Object System.Exception((Get-VstsLocString -Key AZ_ServicePrincipalError), $_.Exception)) } - - if($scopeLevel -eq "Subscription") - { + + if ($scopeLevel -eq "Subscription") { Set-CurrentAzSubscription -SubscriptionId $Endpoint.Data.SubscriptionId -TenantId $Endpoint.Auth.Parameters.TenantId } - } elseif ($Endpoint.Auth.Scheme -eq 'ManagedServiceIdentity') { + Write-Host "##[command]Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue" + $null = Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue + Write-Host "##[command]Clear-AzContext -Scope Process" + $null = Clear-AzContext -Scope Process Retry-Command -Command 'Connect-AzAccount' -Verbose -Args ` @{ Environment=$environmentName; Identity=$true; } - if($scopeLevel -ne "ManagementGroup") { + + if ($scopeLevel -ne "ManagementGroup") { + Set-CurrentAzSubscription -SubscriptionId $Endpoint.Data.SubscriptionId -TenantId $Endpoint.Auth.Parameters.TenantId + } + } elseif ($Endpoint.Auth.Scheme -eq 'WorkloadIdentityFederation') { + $clientAssertionJwt = Get-VstsFederatedToken -serviceConnectionId $connectedServiceNameARM -vstsAccessToken $vstsAccessToken + + Write-Host "##[command]Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue" + $null = Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue + Write-Host "##[command]Clear-AzContext -Scope Process" + $null = Clear-AzContext -Scope Process + + Retry-Command -Command 'Connect-AzAccount' -Verbose -Args ` + @{ + ServicePrincipal=$true; + Tenant=$Endpoint.Auth.Parameters.TenantId; + ApplicationId=$Endpoint.Auth.Parameters.ServicePrincipalId; + FederatedToken=$clientAssertionJwt; + Environment=$environmentName; + } + + if ($scopeLevel -ne "ManagementGroup") { Set-CurrentAzSubscription -SubscriptionId $Endpoint.Data.SubscriptionId -TenantId $Endpoint.Auth.Parameters.TenantId - } + } } else { + Write-Host "##[command]Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue" + $null = Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue + Write-Host "##[command]Clear-AzContext -Scope Process" + $null = Clear-AzContext -Scope Process throw (Get-VstsLocString -Key AZ_UnsupportedAuthScheme0 -ArgumentList $Endpoint.Auth.Scheme) - } + } } function Add-AzureStackAzEnvironment { @@ -165,9 +194,9 @@ function Add-AzureStackAzEnvironment { $azureEnvironmentParams = Get-AzureStackEnvironment -endpoint $Endpoint -name $Name $armEnv = Get-AzEnvironment -Name $name - if($armEnv -ne $null) { + if ($null -ne $armEnv) { Write-Verbose "Updating Az environment $name" -Verbose - Remove-AzEnvironment -Name $name | Out-Null + Remove-AzEnvironment -Name $name | Out-Null } else { Write-Verbose "Adding Az environment $name" -Verbose @@ -204,7 +233,7 @@ function Retry-Command { [Parameter(Mandatory=$false)][int]$retries=5, [Parameter(Mandatory=$false)][int]$secondsDelay=5 ) - + $retryCount = 0 $completed = $false diff --git a/Tasks/Common/VstsAzureHelpers_/Strings/resources.resjson/en-US/resources.resjson b/Tasks/Common/VstsAzureHelpers_/Strings/resources.resjson/en-US/resources.resjson index f3cf5d6589fd..2d73eaf77eb1 100644 --- a/Tasks/Common/VstsAzureHelpers_/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/Common/VstsAzureHelpers_/Strings/resources.resjson/en-US/resources.resjson @@ -2,6 +2,8 @@ "loc.messages.AZ_AzureRMProfileModuleNotFound": "Module 'AzureRM.Profile' not found. The 'AzureRM' module may not be fully installed. Running the following PowerShell commands from an elevated session may resolve the issue: Import-Module AzureRM ; Install-AzureRM", "loc.messages.AZ_CertificateAuthNotSupported": "Certificate based authentication is not supported. Azure PowerShell module is not found.", "loc.messages.AZ_CredentialsError": "There was an error with the Azure credentials used for the deployment.", + "loc.messages.AZ_CouldNotGenerateOidcToken": "Could not generate a client assertion for federated login.", + "loc.messages.AZ_FederatedTokenFailure": "Could not fetch federated token for Workload Identity Federation. {0}", "loc.messages.AZ_ModuleNotFound": "Could not find the modules: '{1}' with Version: '{0}'. If the module was recently installed, retry after restarting the Azure Pipelines task agent.", "loc.messages.AZ_RequiresMinVersion0": "The required minimum version ({0}) of the Azure PowerShell module is not installed.", "loc.messages.AZ_ServicePrincipalError": "There was an error with the service principal used for the deployment.", diff --git a/Tasks/Common/VstsAzureHelpers_/Tests/Initialize-AzureSubscription.WorkloadIdentityFederation.ps1 b/Tasks/Common/VstsAzureHelpers_/Tests/Initialize-AzureSubscription.WorkloadIdentityFederation.ps1 new file mode 100644 index 000000000000..d60a60bf25ef --- /dev/null +++ b/Tasks/Common/VstsAzureHelpers_/Tests/Initialize-AzureSubscription.WorkloadIdentityFederation.ps1 @@ -0,0 +1,61 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\..\Tests\lib\Initialize-Test.ps1 +Microsoft.PowerShell.Core\Import-Module Microsoft.PowerShell.Security +Unregister-Mock Import-Module +Register-Mock Write-VstsTaskError +Register-Mock Get-VstsWebProxy { } +$module = Microsoft.PowerShell.Core\Import-Module $PSScriptRoot\.. -PassThru + +$encryptedToken = ConvertTo-SecureString "test token" -AsPlainText -Force + +$endpoint = @{ + Auth = @{ + Parameters = @{ + ServicePrincipalId = 'Some service principal ID' + TenantId = 'Some tenant ID' + } + Scheme = 'WorkloadIdentityFederation' + } + Data = @{ + SubscriptionId = 'Some subscription ID' + SubscriptionName = 'Some subscription name' + } +} + +$content = @" + {"access_token" : "Dummy Token" } +"@ + +$response = @{ + Content = $content + StatusCode = 200 + StatusDescription = 'OK' +}; + +$variableSets = @( + @{ StorageAccount = 'Some storage account' } +) +foreach ($variableSet in $variableSets) { + Write-Verbose ('-' * 80) + Unregister-Mock Connect-AzAccount + Unregister-Mock Set-CurrentAzSubscription + Unregister-Mock Invoke-WebRequest + Unregister-Mock Set-UserAgent + Unregister-Mock Get-VstsFederatedToken + Unregister-Mock Clear-AzContext + Register-Mock Connect-AzAccount { '' } + Register-Mock Set-CurrentAzSubscription + Register-Mock Set-UserAgent + Register-Mock Invoke-WebRequest { $response } + Register-Mock Get-VstsFederatedToken { "some jwt token" } + Register-Mock Clear-AzContext + + # Act. + $result = & $module Initialize-AzSubscription -Endpoint $endpoint -connectedServiceNameARM 'Some connected service name' -vstsAccessToken $encryptedToken + + Assert-AreEqual $null $result + Assert-WasCalled Set-CurrentAzSubscription -- -SubscriptionId $endpoint.Data.SubscriptionId -TenantId $endpoint.Auth.Parameters.TenantId +} \ No newline at end of file diff --git a/Tasks/Common/VstsAzureHelpers_/Tests/L0.ts b/Tasks/Common/VstsAzureHelpers_/Tests/L0.ts index 103eb97b1994..dceefa022534 100644 --- a/Tasks/Common/VstsAzureHelpers_/Tests/L0.ts +++ b/Tasks/Common/VstsAzureHelpers_/Tests/L0.ts @@ -63,7 +63,7 @@ describe('Common-VstsAzureHelpers_ Suite', function () { it('(Initialize-Azure) throws when service name is null', (done) => { psr.run(path.join(__dirname, 'Initialize-Azure.ThrowsWhenServiceNameIsNull.ps1'), done); }) - it('(Initialize-AzureSubscription) manged service identity should pass ', (done) => { + it('(Initialize-AzureSubscription) managed service identity should pass ', (done) => { psr.run(path.join(__dirname, 'Initialize-AzureSubscription.ManagedServiceIdentity.ps1'), done); }) it('(Initialize-AzureSubscription) passes values when cert auth', (done) => { @@ -96,6 +96,9 @@ describe('Common-VstsAzureHelpers_ Suite', function () { it('(Initialize-AzureSubscription) throws when SP auth and classic 0.9.9', (done) => { psr.run(path.join(__dirname, 'Initialize-AzureSubscription.ThrowsWhenSPAuthAndClassic099.ps1'), done); }) + it('(Initialize-AzureSubscription) workload identity federation should pass', (done) => { + psr.run(path.join(__dirname, 'Initialize-AzureSubscription.WorkloadIdentityFederation.ps1'), done); + }); it('(Initialize-AzureSubscription) throws when unsupported auth', (done) => { psr.run(path.join(__dirname, 'Initialize-AzureSubscription.ThrowsWhenUnsupportedAuth.ps1'), done); }) diff --git a/Tasks/Common/VstsAzureHelpers_/Utility.ps1 b/Tasks/Common/VstsAzureHelpers_/Utility.ps1 index a9b4396f381e..2bce54f964d8 100644 --- a/Tasks/Common/VstsAzureHelpers_/Utility.ps1 +++ b/Tasks/Common/VstsAzureHelpers_/Utility.ps1 @@ -157,6 +157,95 @@ function Get-MsiAccessToken { while ($trialCount -le $retryLimit) } + +function Get-VstsFederatedToken { + param( + [Parameter(Mandatory=$true)] + [string]$serviceConnectionId, + [Parameter(Mandatory=$true)] + [Security.SecureString]$vstsAccessToken + ) + + $OMDirectory = $PSScriptRoot + + $newtonsoftDll = [System.IO.Path]::Combine($OMDirectory, "Newtonsoft.Json.dll") + if (!(Test-Path -LiteralPath $newtonsoftDll -PathType Leaf)) { + Write-Verbose "$newtonsoftDll not found." + throw + } + $jsAssembly = [System.Reflection.Assembly]::LoadFrom($newtonsoftDll) + + $vsServicesDll = [System.IO.Path]::Combine($OMDirectory, "Microsoft.VisualStudio.Services.WebApi.dll") + if (!(Test-Path -LiteralPath $vsServicesDll -PathType Leaf)) { + Write-Verbose "$vsServicesDll not found." + throw + } + try { + Add-Type -LiteralPath $vsServicesDll + } catch { + # The requested type may successfully load now even though the assembly itself is not fully loaded. + Write-Verbose "$($_.Exception.GetType().FullName): $($_.Exception.Message)" + } + + $onAssemblyResolve = [System.ResolveEventHandler] { + param($sender, $e) + + if ($e.Name -like 'Newtonsoft.Json, *') { + return $jsAssembly + } + + Write-Verbose "Unable to resolve assembly name '$($e.Name)'" + return $null + } + [System.AppDomain]::CurrentDomain.add_AssemblyResolve($onAssemblyResolve) + + $taskHttpClient = $null; + try { + Write-Verbose "Trying again to construct the HTTP client." + $decriptedVstsToken = $null + if ($PSVersionTable.PSVersion.Major -lt 7) { + $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($vstsAccessToken) + $decriptedVstsToken = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr) + } + else { + $decriptedVstsToken = ConvertFrom-SecureString -SecureString $vstsAccessToken -AsPlainText + } + $federatedCredential = New-Object Microsoft.VisualStudio.Services.OAuth.VssOAuthAccessTokenCredential($decriptedVstsToken) + $uri = Get-VstsTaskVariable -Name 'System.CollectionUri' -Require + $vssCredentials = New-Object Microsoft.VisualStudio.Services.Common.VssCredentials( + (New-Object Microsoft.VisualStudio.Services.Common.WindowsCredential($false)), # Do not use default credentials. + $federatedCredential, + [Microsoft.VisualStudio.Services.Common.CredentialPromptType]::DoNotPrompt) + $taskHttpClient = Get-VstsVssHttpClient -OMDirectory $OMDirectory ` + -TypeName Microsoft.TeamFoundation.DistributedTask.WebApi.TaskHttpClient ` + -VssCredentials $vssCredentials -Uri $uri + } + finally { + Write-Verbose "Removing assemlby resolver." + [System.AppDomain]::CurrentDomain.remove_AssemblyResolve($onAssemblyResolve) + } + + $planId = Get-VstsTaskVariable -Name 'System.PlanId' -Require + $jobId = Get-VstsTaskVariable -Name 'System.JobId' -Require + $hub = Get-VstsTaskVariable -Name 'System.HostType' -Require + $projectId = Get-VstsTaskVariable -Name 'System.TeamProjectId' -Require + + $tokenResponse = $taskHttpClient.CreateOidcTokenAsync( + $projectId, + $hub, + $planId, + $jobId, + $connectedServiceNameARM, + $null + ).Result + $federatedToken = $tokenResponse.OidcToken + if ($null -eq $federatedToken) { + Write-Verbose "Failed to create OIDC token." + throw (New-Object System.Exception(Get-VstsLocString -Key AZ_CouldNotGenerateOidcToken)) + } + return $federatedToken +} + function Set-UserAgent { [CmdletBinding()] param() diff --git a/Tasks/Common/VstsAzureHelpers_/make.json b/Tasks/Common/VstsAzureHelpers_/make.json index 93c0c1b1f9a0..ffb028130dd4 100644 --- a/Tasks/Common/VstsAzureHelpers_/make.json +++ b/Tasks/Common/VstsAzureHelpers_/make.json @@ -1,5 +1,93 @@ { "externals": { + "nugetv2": [ + { + "name": "Newtonsoft.Json", + "version": "12.0.3", + "repository": "https://www.nuget.org/api/v2/", + "cp": [ + { + "source": "lib/net45/Newtonsoft.Json.dll" + } + ] + }, + { + "name": "Microsoft.AspNet.WebApi.Client", + "version": "5.2.7", + "repository": "https://www.nuget.org/api/v2/", + "cp": [ + { + "source": "lib/net45/System.Net.Http.Formatting.dll" + } + ] + }, + { + "name": "Microsoft.TeamFoundationServer.Client", + "version": "16.170.0", + "repository": "https://www.nuget.org/api/v2/", + "cp": [ + { + "source": "lib/net462/Microsoft.TeamFoundation.Core.WebApi.dll" + }, + { + "source": "lib/net462//Microsoft.TeamFoundation.Core.WebApi.resources.dll", + "dest": "/" + } + ] + }, + { + "name": "Microsoft.TeamFoundation.DistributedTask.Common.Contracts", + "version": "19.216.0-preview", + "repository": "https://www.nuget.org/api/v2/", + "cp": [ + { + "source": [ + "lib/net472/Microsoft.TeamFoundation.DistributedTask.Common.Contracts.dll" + ] + } + ] + }, + { + "name": "Microsoft.TeamFoundation.DistributedTask.WebApi", + "version": "19.216.0-preview", + "repository": "https://www.nuget.org/api/v2/", + "cp": [ + { + "source": [ + "lib/net472/Microsoft.TeamFoundation.DistributedTask.WebApi.dll" + ] + }, + { + "source": [ + "lib/net472//Microsoft.TeamFoundation.DistributedTask.WebApi.resources.dll" + ], + "dest": "/" + } + ] + }, + { + "name": "Microsoft.VisualStudio.Services.Client", + "version": "19.216.0-preview", + "repository": "https://www.nuget.org/api/v2/", + "cp": [ + { + "source": [ + "lib/net472/Microsoft.TeamFoundation.Common.dll", + "lib/net472/Microsoft.VisualStudio.Services.Common.dll", + "lib/net472/Microsoft.VisualStudio.Services.WebApi.dll" + ] + }, + { + "source": [ + "lib/net472//Microsoft.TeamFoundation.Common.resources.dll", + "lib/net472//Microsoft.VisualStudio.Services.Common.resources.dll", + "lib/net472//Microsoft.VisualStudio.Services.WebApi.resources.dll" + ], + "dest": "/" + } + ] + } + ], "archivePackages": [ { "archiveName": "openssl.zip", diff --git a/Tasks/Common/VstsAzureHelpers_/module.json b/Tasks/Common/VstsAzureHelpers_/module.json index c3ba6ba4655a..c782483d851f 100644 --- a/Tasks/Common/VstsAzureHelpers_/module.json +++ b/Tasks/Common/VstsAzureHelpers_/module.json @@ -3,6 +3,8 @@ "AZ_AzureRMProfileModuleNotFound": "Module 'AzureRM.Profile' not found. The 'AzureRM' module may not be fully installed. Running the following PowerShell commands from an elevated session may resolve the issue: Import-Module AzureRM ; Install-AzureRM", "AZ_CertificateAuthNotSupported": "Certificate based authentication is not supported. Azure PowerShell module is not found.", "AZ_CredentialsError": "There was an error with the Azure credentials used for the deployment.", + "AZ_CouldNotGenerateOidcToken": "Could not generate a client assertion for federated login.", + "AZ_FederatedTokenFailure": "Could not fetch federated token for Workload Identity Federation. {0}", "AZ_ModuleNotFound": "Could not find the modules: '{1}' with Version: '{0}'. If the module was recently installed, retry after restarting the Azure Pipelines task agent.", "AZ_RequiresMinVersion0": "The required minimum version ({0}) of the Azure PowerShell module is not installed.", "AZ_ServicePrincipalError": "There was an error with the service principal used for the deployment.", @@ -12,6 +14,6 @@ "AZ_InvalidARMEndpoint": "Specified AzureRM endpoint is invalid.", "AZ_MsiAccessNotConfiguredProperlyFailure": "Could not fetch access token for Managed Identity. Please configure Managed Identity for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: '{0}', Error message: {1}", "AZ_MsiAccessTokenFetchFailure": "Could not fetch access token for Managed Identity. Status code: '{0}', Error message: {1}" , - "AZ_MsiFailure": "Could not fetch access token for Managed Identity. {0}" + "AZ_MsiFailure": "Could not fetch access token for Managed Identity. {0}" } } diff --git a/Tasks/Common/VstsAzureRestHelpers_/Strings/resources.resjson/en-US/resources.resjson b/Tasks/Common/VstsAzureRestHelpers_/Strings/resources.resjson/en-US/resources.resjson index d52e177d67fe..e37a6aa06d49 100644 --- a/Tasks/Common/VstsAzureRestHelpers_/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/Common/VstsAzureRestHelpers_/Strings/resources.resjson/en-US/resources.resjson @@ -1,4 +1,5 @@ { + "loc.messages.AZ_CouldNotGenerateOidcToken": "Could not generate a client assertion for federated login.", "loc.messages.AZ_UnsupportedAuthScheme0": "Unsupported authentication scheme '{0}' for Azure endpoint.", "loc.messages.AZ_SpnAccessTokenFetchFailure": "Not able to fetch token for tenant Id {0}.", "loc.messages.AZ_UserAccessTokenFetchFailure": "Not able to fetch token for given User.", diff --git a/Tasks/Common/VstsAzureRestHelpers_/VstsAzureRestHelpers_.psm1 b/Tasks/Common/VstsAzureRestHelpers_/VstsAzureRestHelpers_.psm1 index 676f3b1e687b..b4261f33f60e 100644 --- a/Tasks/Common/VstsAzureRestHelpers_/VstsAzureRestHelpers_.psm1 +++ b/Tasks/Common/VstsAzureRestHelpers_/VstsAzureRestHelpers_.psm1 @@ -16,6 +16,7 @@ $certificateConnection = 'Certificate' $usernameConnection = 'UserNamePassword' $spnConnection = 'ServicePrincipal' $MsiConnection = 'ManagedServiceIdentity' +$wifConnection = 'WorkloadIdentityFederation' <# @DEPRECATED - DO NOT USE Well-Known ClientId @@ -64,7 +65,7 @@ function Get-AzureUri { function Get-AzureActiverDirectoryResourceId { param([object] [Parameter(Mandatory = $true)] $endpoint) $activeDirectoryResourceid = $null; - + if (($endpoint.Data.Environment) -and ($endpoint.Data.Environment -eq $azureStack)) { if (!$endpoint.Data.ActiveDirectoryServiceEndpointResourceId) { $endpoint = Add-AzureStackDependencyData -Endpoint $endpoint @@ -117,7 +118,7 @@ function Get-ConnectionType { return $connectionType } <# - @DEPRECATED - Get the Bearer Access Token from the Endpoint - + @DEPRECATED - Get the Bearer Access Token from the Endpoint - This flow isn't recommended - https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-desktop-acquire-token-username-password?tabs=dotnet #> function Get-UsernamePasswordAccessToken { @@ -169,7 +170,7 @@ function Get-EnvironmentAuthUrl { Write-Verbose "MSAL - Get-EnvironmentAuthUrl - azureStack is used" $endpoint = Add-AzureStackDependencyData -Endpoint $endpoint $envAuthUrl = $endpoint.Data.environmentAuthorityUrl - } + } else { Write-Verbose "MSAL - Get-EnvironmentAuthUrl - fallback is used" # fallback @@ -210,12 +211,12 @@ function Add-AzureStackDependencyData { $AzureKeyVaultDnsSuffix = "vault.$($stackdomain)".ToLowerInvariant() $AzureKeyVaultServiceEndpointResourceId = $("https://vault.$stackdomain".ToLowerInvariant()) $StorageEndpointSuffix = ($stackdomain).ToLowerInvariant() - + $azureStackEndpointUri = $EndpointURI.ToString().TrimEnd('/') + "/metadata/endpoints?api-version=2015-01-01" Write-Verbose "Retrieving endpoints from the $ResourceManagerEndpoint" $endpointData = Invoke-RestMethod -Uri $azureStackEndpointUri -Method Get -ErrorAction Stop - + if ($endpointData) { $graphEndpoint = $endpointData.graphEndpoint $galleryEndpoint = $endpointData.galleryEndpoint @@ -269,7 +270,7 @@ function Add-AzureStackDependencyData { $Endpoint.Data.activeDirectoryServiceEndpointResourceId = $activeDirectoryServiceEndpointResourceId $Endpoint.Data.AzureKeyVaultDnsSuffix = $AzureKeyVaultDnsSuffix } - } + } else { throw "Unable to fetch Azure Stack Dependency Data." } @@ -279,7 +280,7 @@ function Add-AzureStackDependencyData { function Has-ObjectProperty { [CmdletBinding()] param([Parameter(Mandatory = $true)] $object, - [Parameter(Mandatory = $true)] $propertyName) + [Parameter(Mandatory = $true)] $propertyName) if (Get-Member -inputobject $object -name $propertyName -Membertype Properties) { return $true @@ -294,6 +295,8 @@ function Get-AzureRMAccessToken { [CmdletBinding()] param( [Parameter(Mandatory = $true)] $endpoint, + [string][Parameter(Mandatory=$false)] $connectedServiceNameARM, + [string][Parameter(Mandatory=$false)] $vstsAccessToken, [parameter(Mandatory = $false)] $overrideResourceType = $null, [parameter(Mandatory = $false)] $useMSAL = $false ) @@ -318,6 +321,11 @@ function Get-AzureRMAccessToken { Write-Verbose "MSAL - USE_MSAL couldn't be parsed due to error $exceptionMessage. useMSAL=$useMSAL is used instead" } + if ((-not $useMSAL) -and ($endpoint.Auth.Scheme -eq $wifConnection)) { + Write-Verbose "Overriding useMSAL to ${true} as $wifConnection supports only MSAL" + $useMSAL = $true + } + Write-Verbose "MSAL - useMSAL = $useMSAL" # ManagedIdentity - access token @@ -327,7 +335,7 @@ function Get-AzureRMAccessToken { } # MSAL - access token elseif ($useMSAL) { - $result = Get-AccessTokenMSAL -endpoint $endpoint -overrideResourceType $overrideResourceType + $result = Get-AccessTokenMSAL $endpoint $connectedServiceNameARM $vstsAccessToken $overrideResourceType $accessToken.token_type = $result.TokenType $accessToken.access_token = $result.AccessToken @@ -349,7 +357,9 @@ function Get-AzureRMAccessToken { function Build-MSALInstance { [CmdletBinding()] param( - [Parameter(Mandatory = $true)] $endpoint + [Parameter(Mandatory = $true)] $endpoint, + [string][Parameter(Mandatory=$false)] $connectedServiceNameARM, + [string][Parameter(Mandatory=$false)] $vstsAccessToken ) $clientId = $endpoint.Auth.Parameters.ServicePrincipalId @@ -369,7 +379,15 @@ function Build-MSALInstance { $pfxFilePath, $pfxFilePassword = ConvertTo-Pfx -pemFileContent $pemFileContent $clientCertificate = Get-PfxCertificate -pfxFilePath $pfxFilePath -pfxFilePassword $pfxFilePassword $msalClientInstance = $clientBuilder.WithTenantId($tenantId).WithCertificate($clientCertificate).Build() - } else { + } + elseif ($endpoint.Auth.Scheme -eq $wifConnection) { + Write-Verbose "MSAL - WorkloadIdentityFederation is used"; + + $oidc_token = Get-VstsFederatedToken -serviceConnectionId $connectedServiceNameARM -vstsAccessToken $vstsAccessToken + + $msalClientInstance = $clientBuilder.WithTenantId($tenantId).WithClientAssertion($oidc_token).Build() + } + else { Write-Verbose "MSAL - ServicePrincipal - clientSecret is used."; $clientSecret = $endpoint.Auth.Parameters.ServicePrincipalKey @@ -388,14 +406,16 @@ function Build-MSALInstance { function Get-MSALInstance { [CmdletBinding()] param( - [Parameter(Mandatory = $true)] $endpoint + [Parameter(Mandatory = $true)] $endpoint, + [string][Parameter(Mandatory=$false)] $connectedServiceNameARM, + [string][Parameter(Mandatory=$false)] $vstsAccessToken ) # build MSAL if instance does not exist - if ($script:msalClientInstance -eq $null) { - $script:msalClientInstance = Build-MSALInstance $endpoint + if ($null -eq $script:msalClientInstance) { + $script:msalClientInstance = Build-MSALInstance $endpoint $connectedServiceNameARM $vstsAccessToken } - + return $script:msalClientInstance } @@ -404,16 +424,18 @@ function Get-AccessTokenMSAL { [CmdletBinding()] param( [Parameter(Mandatory = $true)] $endpoint, + [string][Parameter(Mandatory=$false)] $connectedServiceNameARM, + [string][Parameter(Mandatory=$false)] $vstsAccessToken, [parameter(Mandatory = $false)] $overrideResourceType ) - Get-MSALInstance $endpoint + Get-MSALInstance $endpoint $connectedServiceNameARM $vstsAccessToken # prepare MSAL scopes [string] $azureActiveDirectoryResourceId = if ($overrideResourceType) { $overrideResourceType } else { (Get-AzureActiverDirectoryResourceId -endpoint $endpoint) } $azureActiveDirectoryResourceId = $azureActiveDirectoryResourceId + "/.default" $scopes = [Collections.Generic.List[string]]@($azureActiveDirectoryResourceId) - + try { Write-Verbose "Fetching Access Token - MSAL" $tokenResult = $script:msalClientInstance.AcquireTokenForClient($scopes).ExecuteAsync().GetAwaiter().GetResult() @@ -464,7 +486,7 @@ function Get-SpnAccessToken { # Call Rest API to fetch AccessToken Write-Verbose "Fetching Access Token" - + try { $accessToken = Invoke-RestMethod -Uri $authUri -Method $method -Body $body -ContentType $script:formContentType return $accessToken @@ -505,15 +527,15 @@ function Get-MsiAccessToken { $method = "GET" $apiVersion = "2018-02-01"; $authUri = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=" + $apiVersion + "&resource=" + $endPointUrl + $msiClientId; - + # Call Rest API to fetch AccessToken Write-Verbose "Fetching Access Token For MSI" - + try { $retryLimit = 5; $response = Invoke-WebRequest -Uri $authUri -Method $method -Headers @{Metadata = "true" } -UseBasicParsing - # Action on the based of response + # Action on the based of response if (($response.StatusCode -eq 429) -or ($response.StatusCode -eq 500)) { if ($retryCount -lt $retryLimit) { $retryCount += 1 @@ -532,7 +554,7 @@ function Get-MsiAccessToken { else { throw (Get-VstsLocString -Key AZ_MsiAccessNotConfiguredProperlyFailure -ArgumentList $response.StatusCode, $response.StatusDescription) } - + } catch { $exceptionMessage = $_.Exception.Message.ToString() @@ -568,13 +590,13 @@ function Get-SpnAccessTokenUsingCertificate { } Write-Verbose "Fetching access token using client certificate." - - # load the ADAL library + + # load the ADAL library Add-Type -Path $PSScriptRoot\Microsoft.IdentityModel.Clients.ActiveDirectory.dll $pemFileContent = $endpoint.Auth.Parameters.ServicePrincipalCertificate $pfxFilePath, $pfxFilePassword = ConvertTo-Pfx -pemFileContent $pemFileContent - + $clientCertificate = Get-PfxCertificate -pfxFilePath $pfxFilePath -pfxFilePassword $pfxFilePassword $servicePrincipalId = $endpoint.Auth.Parameters.ServicePrincipalId @@ -631,7 +653,7 @@ function Get-SpnAccessTokenUsingCertificate { function Get-PfxCertificate { param( - [string][Parameter(Mandatory = $true)] $pfxFilePath, + [string][Parameter(Mandatory = $true)] $pfxFilePath, [string][Parameter(Mandatory = $true)] $pfxFilePassword ) @@ -657,7 +679,7 @@ function Get-AzStorageKeys { [CmdletBinding()] param([String] [Parameter(Mandatory = $true)] $storageAccountName, [Object] [Parameter(Mandatory = $true)] $endpoint) - + try { $subscriptionId = $endpoint.Data.SubscriptionId.ToLower() $azureUri = Get-AzureUri $endpoint @@ -673,7 +695,7 @@ function Get-AzStorageKeys { } catch { $exceptionMessage = $_.Exception.Message.ToString() - Write-Verbose "Exception : $exceptionMessage" + Write-Verbose "Exception : $exceptionMessage" $parsedException = Parse-Exception($_.Exception) if ($parsedException) { $exceptionMessage = $parsedException @@ -685,14 +707,16 @@ function Get-AzStorageKeys { function Get-AzRMStorageKeys { [CmdletBinding()] - param([String] [Parameter(Mandatory = $true)] $resourceGroupName, - [String] [Parameter(Mandatory = $true)] $storageAccountName, - [Object] [Parameter(Mandatory = $true)] $endpoint) + param([string] [Parameter(Mandatory = $true)] $resourceGroupName, + [string] [Parameter(Mandatory = $true)] $storageAccountName, + [object] [Parameter(Mandatory = $true)] $endpoint, + [string][Parameter(Mandatory=$false)] $connectedServiceNameARM, + [string][Parameter(Mandatory=$false)] $vstsAccessToken) try { - $accessToken = Get-AzureRMAccessToken $endpoint + $accessToken = Get-AzureRMAccessToken $endpoint $connectedServiceNameARM $vstsAccessToken - $resourceGroupDetails = Get-AzRmResourceGroup $resourceGroupName $endpoint + $resourceGroupDetails = Get-AzRmResourceGroup $resourceGroupName $endpoint $accessToken $resourceGroupId = $resourceGroupDetails.id $method = "POST" @@ -705,7 +729,7 @@ function Get-AzRMStorageKeys { } catch { $exceptionMessage = $_.Exception.Message.ToString() - Write-Verbose "Exception : $exceptionMessage" + Write-Verbose "Exception : $exceptionMessage" $parsedException = Parse-Exception($_.Exception) if ($parsedException) { $exceptionMessage = $parsedException @@ -720,11 +744,13 @@ function Get-AzRmVmCustomScriptExtension { param([String] [Parameter(Mandatory = $true)] $resourceGroupName, [String] [Parameter(Mandatory = $true)] $vmName, [String] [Parameter(Mandatory = $true)] $Name, - [Object] [Parameter(Mandatory = $true)] $endpoint) + [Object] [Parameter(Mandatory = $true)] $endpoint, + [string] [Parameter(Mandatory=$false)] $connectedServiceNameARM, + [string] [Parameter(Mandatory=$false)] $vstsAccessToken) try { - $accessToken = Get-AzureRMAccessToken $endpoint - $resourceGroupDetails = Get-AzRmResourceGroup $resourceGroupName $endpoint + $accessToken = Get-AzureRMAccessToken $endpoint $connectedServiceNameARM $vstsAccessToken + $resourceGroupDetails = Get-AzRmResourceGroup $resourceGroupName $endpoint $accessToken $resourceGroupId = $resourceGroupDetails.id if (($endpoint.Data.Environment) -and ($endpoint.Data.Environment -eq $azureStack)) { @@ -745,7 +771,7 @@ function Get-AzRmVmCustomScriptExtension { } catch { $exceptionMessage = $_.Exception.Message.ToString() - Write-Verbose "Exception : $exceptionMessage" + Write-Verbose "Exception : $exceptionMessage" $parsedException = Parse-Exception($_.Exception) if ($parsedException) { $exceptionMessage = $parsedException @@ -760,11 +786,13 @@ function Remove-AzRmVmCustomScriptExtension { param([String] [Parameter(Mandatory = $true)] $resourceGroupName, [String] [Parameter(Mandatory = $true)] $vmName, [String] [Parameter(Mandatory = $true)] $Name, - [Object] [Parameter(Mandatory = $true)] $endpoint) + [Object] [Parameter(Mandatory = $true)] $endpoint, + [string] [Parameter(Mandatory=$false)] $connectedServiceNameARM, + [string] [Parameter(Mandatory=$false)] $vstsAccessToken) try { - $accessToken = Get-AzureRMAccessToken $endpoint - $resourceGroupDetails = Get-AzRmResourceGroup $resourceGroupName $endpoint + $accessToken = Get-AzureRMAccessToken $endpoint $connectedServiceNameARM $vstsAccessToken + $resourceGroupDetails = Get-AzRmResourceGroup $resourceGroupName $endpoint $accessToken $resourceGroupId = $resourceGroupDetails.id $method = "DELETE" @@ -778,7 +806,7 @@ function Remove-AzRmVmCustomScriptExtension { } catch { $exceptionMessage = $_.Exception.Message.ToString() - Write-Verbose "Exception : $exceptionMessage" + Write-Verbose "Exception : $exceptionMessage" $parsedException = Parse-Exception($_.Exception) if ($parsedException) { $exceptionMessage = $parsedException @@ -808,7 +836,7 @@ function Get-AzStorageAccount { } catch { $exceptionMessage = $_.Exception.Message.ToString() - Write-Verbose "Exception : $exceptionMessage" + Write-Verbose "Exception : $exceptionMessage" $parsedException = Parse-Exception($_.Exception) if ($parsedException) { $exceptionMessage = $parsedException @@ -822,11 +850,13 @@ function Get-AzRmStorageAccount { [CmdletBinding()] param([String] [Parameter(Mandatory = $true)] $resourceGroupName, [String] [Parameter(Mandatory = $true)] $storageAccountName, - [Object] [Parameter(Mandatory = $true)] $endpoint) + [Object] [Parameter(Mandatory = $true)] $endpoint, + [string] [Parameter(Mandatory=$false)] $connectedServiceNameARM, + [string] [Parameter(Mandatory=$false)] $vstsAccessToken) try { - $accessToken = Get-AzureRMAccessToken $endpoint - $resourceGroupDetails = Get-AzRmResourceGroup $resourceGroupName $endpoint + $accessToken = Get-AzureRMAccessToken $endpoint $connectedServiceNameARM $vstsAccessToken + $resourceGroupDetails = Get-AzRmResourceGroup $resourceGroupName $endpoint $accessToken $resourceGroupId = $resourceGroupDetails.id $method = "GET" @@ -837,7 +867,7 @@ function Get-AzRmStorageAccount { $storageAccountUnformatted = Invoke-RestMethod -Uri $uri -Method $method -Headers $headers Write-Verbose "Constructing the storage account object" - + $storageAccount = New-Object -TypeName PSObject $storageAccount | Add-Member -type NoteProperty -name id -value $storageAccountUnformatted.id $storageAccount | Add-Member -type NoteProperty -name kind -value $storageAccountUnformatted.kind @@ -855,7 +885,7 @@ function Get-AzRmStorageAccount { } catch { $exceptionMessage = $_.Exception.Message.ToString() - Write-Verbose "Exception : $exceptionMessage" + Write-Verbose "Exception : $exceptionMessage" $parsedException = Parse-Exception($_.Exception) if ($parsedException) { $exceptionMessage = $parsedException @@ -868,10 +898,10 @@ function Get-AzRmStorageAccount { function Get-AzRmResourceGroup { [CmdletBinding()] param([String] [Parameter(Mandatory = $true)] $resourceGroupName, - [Object] [Parameter(Mandatory = $true)] $endpoint) + [Object] [Parameter(Mandatory = $true)] $endpoint, + [Parameter(Mandatory = $true)] $accessToken) try { - $accessToken = Get-AzureRMAccessToken $endpoint $subscriptionId = $endpoint.Data.SubscriptionId.ToLower() $method = "GET" @@ -884,7 +914,7 @@ function Get-AzRmResourceGroup { } catch { $exceptionMessage = $_.Exception.Message.ToString() - Write-Verbose "Exception : $exceptionMessage" + Write-Verbose "Exception : $exceptionMessage" $parsedException = Parse-Exception($_.Exception) if ($parsedException) { $exceptionMessage = $parsedException @@ -966,9 +996,11 @@ function Add-AzureRmSqlServerFirewall { [String] [Parameter(Mandatory = $true)] $startIPAddress, [String] [Parameter(Mandatory = $true)] $endIPAddress, [String] [Parameter(Mandatory = $true)] $serverName, - [String] [Parameter(Mandatory = $true)] $firewallRuleName) + [String] [Parameter(Mandatory = $true)] $firewallRuleName, + [string] [Parameter(Mandatory = $false)] $connectedServiceNameARM, + [string] [Parameter(Mandatory = $false)] $vstsAccessToken) - $accessToken = Get-AzureRMAccessToken $endpoint + $accessToken = Get-AzureRMAccessToken $endpoint $connectedServiceNameARM $vstsAccessToken # get azure sql server resource Id $azureResourceId = Get-AzureSqlDatabaseServerResourceId -endpoint $endpoint -serverName $serverName -accessToken $accessToken @@ -1015,9 +1047,11 @@ function Remove-AzureRmSqlServerFirewall { [CmdletBinding()] param([Object] [Parameter(Mandatory = $true)] $endpoint, [String] [Parameter(Mandatory = $true)] $serverName, - [String] [Parameter(Mandatory = $true)] $firewallRuleName) + [String] [Parameter(Mandatory = $true)] $firewallRuleName, + [string] [Parameter(Mandatory = $false)] $connectedServiceNameARM, + [string] [Parameter(Mandatory = $false)] $vstsAccessToken) - $accessToken = Get-AzureRMAccessToken $endpoint + $accessToken = Get-AzureRMAccessToken $endpoint $connectedServiceNameARM $vstsAccessToken # Fetch Azure SQL server resource Id $azureResourceId = Get-AzureSqlDatabaseServerResourceId -endpoint $endpoint -serverName $serverName -accessToken $accessToken @@ -1035,8 +1069,10 @@ function Add-AzureSqlDatabaseServerFirewallRule { [String] [Parameter(Mandatory = $true)] $startIPAddress, [String] [Parameter(Mandatory = $true)] $endIPAddress, [String] [Parameter(Mandatory = $true)] $serverName, - [String] [Parameter(Mandatory = $true)] $firewallRuleName) - + [String] [Parameter(Mandatory = $true)] $firewallRuleName, + [string] [Parameter(Mandatory = $false)] $connectedServiceNameARM, + [string] [Parameter(Mandatory = $false)] $vstsAccessToken) + Trace-VstsEnteringInvocation $MyInvocation try { @@ -1048,8 +1084,8 @@ function Add-AzureSqlDatabaseServerFirewallRule { Add-LegacyAzureSqlServerFirewall -endpoint $endpoint -serverName $serverName -startIPAddress $startIPAddress -endIPAddress $endIPAddress -firewallRuleName $firewallRuleName } elseif (IsAzureRmConnection $connectionType) { - - Add-AzureRmSqlServerFirewall -endpoint $endpoint -serverName $serverName -startIPAddress $startIPAddress -endIPAddress $endIPAddress -firewallRuleName $firewallRuleName + Add-AzureRmSqlServerFirewall -endpoint $endpoint -serverName $serverName -startIPAddress $startIPAddress -endIPAddress $endIPAddress ` + -firewallRuleName $firewallRuleName -connectedServiceNameARM $connectedServiceNameARM -vstsAccessToken $vstsAccessToken } else { throw (Get-VstsLocString -Key AZ_UnsupportedAuthScheme0 -ArgumentList $connectionType) @@ -1070,7 +1106,9 @@ function Remove-AzureSqlDatabaseServerFirewallRule { [CmdletBinding()] param([Object] [Parameter(Mandatory = $true)] $endpoint, [String] [Parameter(Mandatory = $true)] $serverName, - [String] [Parameter(Mandatory = $true)] $firewallRuleName) + [String] [Parameter(Mandatory = $true)] $firewallRuleName, + [string] [Parameter(Mandatory = $false)] $connectedServiceNameARM, + [string] [Parameter(Mandatory = $false)] $vstsAccessToken) Trace-VstsEnteringInvocation $MyInvocation @@ -1083,7 +1121,7 @@ function Remove-AzureSqlDatabaseServerFirewallRule { Remove-LegacyAzureSqlServerFirewall -endpoint $endpoint -serverName $serverName -firewallRuleName $firewallRuleName } elseif (IsAzureRmConnection $connectionType) { - Remove-AzureRmSqlServerFirewall -endpoint $endpoint -serverName $serverName -firewallRuleName $firewallRuleName + Remove-AzureRmSqlServerFirewall $endpoint $serverName $firewallRuleName $connectedServiceNameARM $vstsAccessToken } else { throw (Get-VstsLocString -Key AZ_UnsupportedAuthScheme0 -ArgumentList $connectionType) @@ -1137,11 +1175,11 @@ function Parse-Exception($exception) { $exceptionMessage = $responseBody } if ($response.statusCode -eq 404 -or (-not $exceptionMessage)) { - $exceptionMessage += " Please verify request URL : $($response.ResponseUri)" + $exceptionMessage += " Please verify request URL : $($response.ResponseUri)" } return $exceptionMessage } - } + } catch { Write-verbose "Unable to parse exception: " + $_.Exception.ToString() } @@ -1152,19 +1190,21 @@ function Parse-Exception($exception) { function Get-AzureNetworkInterfaceDetails { [CmdletBinding()] param([String] [Parameter(Mandatory = $true)] $resourceGroupName, - [Object] [Parameter(Mandatory = $true)] $endpoint) + [Object] [Parameter(Mandatory = $true)] $endpoint, + [string] [Parameter(Mandatory=$false)] $connectedServiceNameARM, + [string] [Parameter(Mandatory=$false)] $vstsAccessToken) - $accessToken = Get-AzureRMAccessToken $endpoint + $accessToken = Get-AzureRMAccessToken $endpoint $connectedServiceNameARM $vstsAccessToken $subscriptionId = $endpoint.Data.SubscriptionId.ToLower() Write-Verbose "[Azure Rest Call] Get Network Interface Details" - + $method = "GET" $uri = "$($endpoint.Url)/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Network/networkInterfaces?api-version=$azureStackapiVersion" $headers = @{Authorization = ("{0} {1}" -f $accessToken.token_type, $accessToken.access_token) } $networkInterfaceDetails = Invoke-RestMethod -Uri $uri -Method $method -Headers $headers -ContentType $script:jsonContentType - + if (-not $networkInterfaceDetails) { throw (Get-VstsLocString -Key AZ_UnableToFetchNetworkInterfacesDetails) } @@ -1172,16 +1212,18 @@ function Get-AzureNetworkInterfaceDetails { if ($networkInterfaceDetails.value) { return $networkInterfaceDetails.value | ForEach-Object { Add-PropertiesToRoot -rootObject $_ } } - + return $networkInterfaceDetails.value } function Get-AzurePublicIpAddressDetails { [CmdletBinding()] param([String] [Parameter(Mandatory = $true)] $resourceGroupName, - [Object] [Parameter(Mandatory = $true)] $endpoint) + [Object] [Parameter(Mandatory = $true)] $endpoint, + [string] [Parameter(Mandatory = $false)] $connectedServiceNameARM, + [string] [Parameter(Mandatory = $false)] $vstsAccessToken) - $accessToken = Get-AzureRMAccessToken $endpoint + $accessToken = Get-AzureRMAccessToken $endpoint $connectedServiceNameARM $vstsAccessToken $subscriptionId = $endpoint.Data.SubscriptionId.ToLower() Write-Verbose "[Azure Rest Call] Get Public IP Addresses Details" @@ -1206,9 +1248,11 @@ function Get-AzurePublicIpAddressDetails { function Get-AzureLoadBalancersDetails { [CmdletBinding()] param([String] [Parameter(Mandatory = $true)] $resourceGroupName, - [Object] [Parameter(Mandatory = $true)] $endpoint) + [Object] [Parameter(Mandatory = $true)] $endpoint, + [string] [Parameter(Mandatory = $false)] $connectedServiceNameARM, + [string] [Parameter(Mandatory = $false)] $vstsAccessToken) - $accessToken = Get-AzureRMAccessToken $endpoint + $accessToken = Get-AzureRMAccessToken $endpoint $connectedServiceNameARM $vstsAccessToken $subscriptionId = $endpoint.Data.SubscriptionId.ToLower() Write-Verbose "[Azure Rest Call] Get Load Balancers details" @@ -1234,11 +1278,13 @@ function Get-AzureLoadBalancerDetails { [CmdletBinding()] param([String] [Parameter(Mandatory = $true)] $resourceGroupName, [String] [Parameter(Mandatory = $true)] $name, - [Object] [Parameter(Mandatory = $true)] $endpoint) + [Object] [Parameter(Mandatory = $true)] $endpoint, + [string] [Parameter(Mandatory = $false)] $connectedServiceNameARM, + [string] [Parameter(Mandatory = $false)] $vstsAccessToken) - $accessToken = Get-AzureRMAccessToken $endpoint + $accessToken = Get-AzureRMAccessToken $endpoint $connectedServiceNameARM $vstsAccessToken $subscriptionId = $endpoint.Data.SubscriptionId.ToLower() - + Write-Verbose "[Azure Rest Call] Get Load balancer details with name : $name" $method = "GET" @@ -1246,11 +1292,11 @@ function Get-AzureLoadBalancerDetails { $headers = @{Authorization = ("{0} {1}" -f $accessToken.token_type, $accessToken.access_token) } $loadBalancerDetails = Invoke-RestMethod -Uri $uri -Method $method -Headers $headers -ContentType $script:jsonContentType - + if ($loadBalancerDetails) { return $loadBalancersDetails | ForEach-Object { Add-PropertiesToRoot -rootObject $_ } } - + return $loadBalancerDetails } @@ -1272,7 +1318,7 @@ function Get-AzureRMLoadBalancerInboundNatRuleConfigDetails { param([Object] [Parameter(Mandatory = $true)] $loadBalancer) $inboundNatRules = $loadBalancer.inboundNatRules - + if ($inboundNatRules) { return Add-PropertiesToRoot -rootObject $inboundNatRules } @@ -1305,7 +1351,7 @@ function ConvertTo-Pfx { else { $pemFilePath = "$ENV:System_DefaultWorkingDirectory\clientcertificate.pem" $pfxFilePath = "$ENV:System_DefaultWorkingDirectory\clientcertificate.pfx" - $pfxPasswordFilePath = "$ENV:System_DefaultWorkingDirectory\clientcertificatepassword.txt" + $pfxPasswordFilePath = "$ENV:System_DefaultWorkingDirectory\clientcertificatepassword.txt" } # save the PEM certificate to a PEM file @@ -1317,12 +1363,93 @@ function ConvertTo-Pfx { $openSSLExePath = "$PSScriptRoot\openssl\openssl.exe" $openSSLArgs = "pkcs12 -export -in $pemFilePath -out $pfxFilePath -password file:`"$pfxPasswordFilePath`"" - + Invoke-VstsTool -FileName $openSSLExePath -Arguments $openSSLArgs -RequireExitCodeZero return $pfxFilePath, $pfxFilePassword } +function Get-VstsFederatedToken { + param( + [Parameter(Mandatory=$true)] + [string]$serviceConnectionId, + [Parameter(Mandatory=$true)] + [string]$vstsAccessToken + ) + + $OMDirectory = $PSScriptRoot + + $newtonsoftDll = [System.IO.Path]::Combine($OMDirectory, "Newtonsoft.Json.dll") + if (!(Test-Path -LiteralPath $newtonsoftDll -PathType Leaf)) { + Write-Verbose "$newtonsoftDll not found." + throw + } + $jsAssembly = [System.Reflection.Assembly]::LoadFrom($newtonsoftDll) + + $vsServicesDll = [System.IO.Path]::Combine($OMDirectory, "Microsoft.VisualStudio.Services.WebApi.dll") + if (!(Test-Path -LiteralPath $vsServicesDll -PathType Leaf)) { + Write-Verbose "$vsServicesDll not found." + throw + } + try { + Add-Type -LiteralPath $vsServicesDll + } catch { + # The requested type may successfully load now even though the assembly itself is not fully loaded. + Write-Verbose "$($_.Exception.GetType().FullName): $($_.Exception.Message)" + } + + $onAssemblyResolve = [System.ResolveEventHandler] { + param($sender, $e) + + if ($e.Name -like 'Newtonsoft.Json, *') { + return $jsAssembly + } + + Write-Verbose "Unable to resolve assembly name '$($e.Name)'" + return $null + } + [System.AppDomain]::CurrentDomain.add_AssemblyResolve($onAssemblyResolve) + + $taskHttpClient = $null; + try { + Write-Verbose "Trying again to construct the HTTP client." + $federatedCredential = New-Object Microsoft.VisualStudio.Services.OAuth.VssOAuthAccessTokenCredential($vstsAccessToken) + $uri = Get-VstsTaskVariable -Name 'System.CollectionUri' -Require + $vssCredentials = New-Object Microsoft.VisualStudio.Services.Common.VssCredentials( + (New-Object Microsoft.VisualStudio.Services.Common.WindowsCredential($false)), # Do not use default credentials. + $federatedCredential, + [Microsoft.VisualStudio.Services.Common.CredentialPromptType]::DoNotPrompt) + $taskHttpClient = Get-VstsVssHttpClient -OMDirectory $OMDirectory ` + -TypeName Microsoft.TeamFoundation.DistributedTask.WebApi.TaskHttpClient ` + -VssCredentials $vssCredentials -Uri $uri + } + finally { + Write-Verbose "Removing assemlby resolver." + [System.AppDomain]::CurrentDomain.remove_AssemblyResolve($onAssemblyResolve) + } + + $planId = Get-VstsTaskVariable -Name 'System.PlanId' -Require + $jobId = Get-VstsTaskVariable -Name 'System.JobId' -Require + $hub = Get-VstsTaskVariable -Name 'System.HostType' -Require + $projectId = Get-VstsTaskVariable -Name 'System.TeamProjectId' -Require + + $tokenResponse = $taskHttpClient.CreateOidcTokenAsync( + $projectId, + $hub, + $planId, + $jobId, + $connectedServiceNameARM, + $null + ).Result + $federatedToken = $tokenResponse.OidcToken + if ($null -eq $federatedToken -or $federatedToken -eq [string]::Empty) { + Write-Verbose "Failed to create OIDC token." + throw (New-Object System.Exception(Get-VstsLocString -Key AZ_CouldNotGenerateOidcToken)) + } + Write-Verbose "Generated OIDC token." + return $federatedToken +} + # Export only the public function. Export-ModuleMember -Function Add-AzureSqlDatabaseServerFirewallRule Export-ModuleMember -Function Remove-AzureSqlDatabaseServerFirewallRule diff --git a/Tasks/Common/VstsAzureRestHelpers_/make.json b/Tasks/Common/VstsAzureRestHelpers_/make.json index 526424904ba7..20805f836433 100644 --- a/Tasks/Common/VstsAzureRestHelpers_/make.json +++ b/Tasks/Common/VstsAzureRestHelpers_/make.json @@ -1,6 +1,26 @@ { "externals": { "nugetv2": [ + { + "name": "Newtonsoft.Json", + "version": "12.0.3", + "repository": "https://www.nuget.org/api/v2/", + "cp": [ + { + "source": "lib/net45/Newtonsoft.Json.dll" + } + ] + }, + { + "name": "Microsoft.AspNet.WebApi.Client", + "version": "5.2.7", + "repository": "https://www.nuget.org/api/v2/", + "cp": [ + { + "source": "lib/net45/System.Net.Http.Formatting.dll" + } + ] + }, { "name": "Microsoft.IdentityModel.Clients.ActiveDirectory", "version": "2.23.302261847", @@ -32,6 +52,72 @@ "dest": "msal" } ] + }, + { + "name": "Microsoft.TeamFoundationServer.Client", + "version": "16.170.0", + "repository": "https://www.nuget.org/api/v2/", + "cp": [ + { + "source": "lib/net462/Microsoft.TeamFoundation.Core.WebApi.dll" + }, + { + "source": "lib/net462//Microsoft.TeamFoundation.Core.WebApi.resources.dll", + "dest": "/" + } + ] + }, + { + "name": "Microsoft.TeamFoundation.DistributedTask.Common.Contracts", + "version": "19.216.0-preview", + "repository": "https://www.nuget.org/api/v2/", + "cp": [ + { + "source": [ + "lib/net472/Microsoft.TeamFoundation.DistributedTask.Common.Contracts.dll" + ] + } + ] + }, + { + "name": "Microsoft.TeamFoundation.DistributedTask.WebApi", + "version": "19.216.0-preview", + "repository": "https://www.nuget.org/api/v2/", + "cp": [ + { + "source": [ + "lib/net472/Microsoft.TeamFoundation.DistributedTask.WebApi.dll" + ] + }, + { + "source": [ + "lib/net472//Microsoft.TeamFoundation.DistributedTask.WebApi.resources.dll" + ], + "dest": "/" + } + ] + }, + { + "name": "Microsoft.VisualStudio.Services.Client", + "version": "19.216.0-preview", + "repository": "https://www.nuget.org/api/v2/", + "cp": [ + { + "source": [ + "lib/net472/Microsoft.TeamFoundation.Common.dll", + "lib/net472/Microsoft.VisualStudio.Services.Common.dll", + "lib/net472/Microsoft.VisualStudio.Services.WebApi.dll" + ] + }, + { + "source": [ + "lib/net472//Microsoft.TeamFoundation.Common.resources.dll", + "lib/net472//Microsoft.VisualStudio.Services.Common.resources.dll", + "lib/net472//Microsoft.VisualStudio.Services.WebApi.resources.dll" + ], + "dest": "/" + } + ] } ], "archivePackages": [ diff --git a/Tasks/Common/VstsAzureRestHelpers_/module.json b/Tasks/Common/VstsAzureRestHelpers_/module.json index 656547567b6a..ea2597a78805 100644 --- a/Tasks/Common/VstsAzureRestHelpers_/module.json +++ b/Tasks/Common/VstsAzureRestHelpers_/module.json @@ -1,5 +1,6 @@ { "messages": { + "AZ_CouldNotGenerateOidcToken": "Could not generate a client assertion for federated login.", "AZ_UnsupportedAuthScheme0": "Unsupported authentication scheme '{0}' for Azure endpoint.", "AZ_SpnAccessTokenFetchFailure": "Not able to fetch token for tenant Id {0}.", "AZ_UserAccessTokenFetchFailure": "Not able to fetch token for given User.", diff --git a/Tasks/SqlAzureDacpacDeploymentV1/DeploySqlAzure.ps1 b/Tasks/SqlAzureDacpacDeploymentV1/DeploySqlAzure.ps1 index fdde2e595ec5..cd04ff96c572 100644 --- a/Tasks/SqlAzureDacpacDeploymentV1/DeploySqlAzure.ps1 +++ b/Tasks/SqlAzureDacpacDeploymentV1/DeploySqlAzure.ps1 @@ -58,7 +58,7 @@ try { # Telemetry for endpoint id $encodedServerName = GetSHA256String($serverName) $encodedDatabaseName = GetSHA256String($databaseName) - $telemetryJsonContent = -join ("{`"endpointId`":`"$connectedServiceName`",", + $telemetryJsonContent = -join ("{`"endpointId`":`"$connectedServiceName`",", "`"subscriptionId`":`"$subscriptionId`",", "`"serverName`": `"$encodedServerName`",", "`"databaseName`": `"$encodedDatabaseName`"}") @@ -101,7 +101,10 @@ try { $dbDns = $endpoint.Data.sqlDatabaseDnsSuffix $dbDns = $dbDns.Trim(".") $dbUrl = (New-Object -TypeName UriBuilder -ArgumentList @("https", $dbDns)).Uri - $accessToken = (Get-AzureRMAccessToken -endpoint $endpoint -overrideResourceType $dbUrl).access_token + $vstsEndpoint = Get-VstsEndpoint -Name SystemVssConnection -Require + $vstsAccessToken = $vstsEndpoint.auth.parameters.AccessToken + $token = Get-AzureRMAccessToken -endpoint $endpoint -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken -overrideResourceType $dbUrl + $accessToken = $token.access_token } # Checks for the very basic consistency of the Server Name @@ -112,7 +115,10 @@ try { throw (Get-VstsLocString -Key "SAD_InvalidDeploymentActionForSQLOperations" -ArgumentList $deploymentAction) } - $firewallRuleName, $isFirewallConfigured = Add-FirewallRule -endpoint $endpoint -authenticationType $authenticationType -serverName $serverName -databaseName $databaseName -sqlUsername $sqlUsername -sqlPassword $sqlPassword -connectionString $connectionString -ipDetectionMethod $ipDetectionMethod -startIPAddress $startIpAddress -endIPAddress $endIpAddress -token $accessToken + $firewallRuleName, $isFirewallConfigured = Add-FirewallRule -endpoint $endpoint -authenticationType $authenticationType -serverName $serverName ` + -databaseName $databaseName -sqlUsername $sqlUsername -sqlPassword $sqlPassword -connectionString $connectionString ` + -ipDetectionMethod $ipDetectionMethod -startIPAddress $startIpAddress -endIPAddress $endIpAddress -token $accessToken ` + -connectedServiceNameARM $connectedServiceName -vstsAccessToken $vstsAccessToken $firewallConfigWaitTime = $env:SqlFirewallConfigWaitTime @@ -226,7 +232,8 @@ finally { Write-Verbose "Deleting $firewallRuleName" $serverFriendlyName = $serverName.split(".")[0] Delete-AzureSqlDatabaseServerFirewallRule -serverName $serverFriendlyName -firewallRuleName $firewallRuleName -endpoint $endpoint ` - -isFirewallConfigured $isFirewallConfigured -deleteFireWallRule $deleteFirewallRule + -isFirewallConfigured $isFirewallConfigured -deleteFireWallRule $deleteFirewallRule -connectedServiceNameARM $connectedServiceName ` + -vstsAccessToken $vstsAccessToken } else { Write-Verbose "No Firewall Rule was added" diff --git a/Tasks/SqlAzureDacpacDeploymentV1/SqlAzureActions.ps1 b/Tasks/SqlAzureDacpacDeploymentV1/SqlAzureActions.ps1 index 42f98c3d9f7f..7d8ffe87e171 100644 --- a/Tasks/SqlAzureDacpacDeploymentV1/SqlAzureActions.ps1 +++ b/Tasks/SqlAzureDacpacDeploymentV1/SqlAzureActions.ps1 @@ -406,7 +406,9 @@ function Add-FirewallRule { [string] $ipDetectionMethod, [string] $startIPAddress, [string] $endIPAddress, - [String] $token + [String] $token, + [string] $connectedServiceNameARM, + [string] $vstsAccessToken ) # Test and get IPRange for autoDetect IpDetectionMethod @@ -425,7 +427,8 @@ function Add-FirewallRule { if ($ipAddressRange.Count -ne 0) { $serverFriendlyName = $serverName.split(".")[0] - $firewallSettings = Create-AzureSqlDatabaseServerFirewallRule -startIP $ipAddressRange.StartIPAddress -endIP $ipAddressRange.EndIPAddress -serverName $serverFriendlyName -endpoint $endpoint + $firewallSettings = Create-AzureSqlDatabaseServerFirewallRule -startIP $ipAddressRange.StartIPAddress -endIP $ipAddressRange.EndIPAddress ` + -serverName $serverFriendlyName -endpoint $endpoint -connectedServiceNameARM $connectedServiceNameARM -vstsAccessToken $vstsAccessToken Write-Verbose ($firewallSettings | Format-List | Out-String) $firewallRuleName = $firewallSettings.RuleName diff --git a/Tasks/SqlAzureDacpacDeploymentV1/Utility.ps1 b/Tasks/SqlAzureDacpacDeploymentV1/Utility.ps1 index 057a8ab49243..efb893c32411 100644 --- a/Tasks/SqlAzureDacpacDeploymentV1/Utility.ps1 +++ b/Tasks/SqlAzureDacpacDeploymentV1/Utility.ps1 @@ -39,12 +39,15 @@ function Create-AzureSqlDatabaseServerFirewallRule { param([String] [Parameter(Mandatory = $true)] $startIp, [String] [Parameter(Mandatory = $true)] $endIp, [String] [Parameter(Mandatory = $true)] $serverName, - [Object] [Parameter(Mandatory = $true)] $endpoint) + [Object] [Parameter(Mandatory = $true)] $endpoint, + [string] [Parameter(Mandatory = $false)] $connectedServiceNameARM, + [string] [Parameter(Mandatory = $false)] $vstsAccessToken) [HashTable]$FirewallSettings = @{} $firewallRuleName = [System.Guid]::NewGuid().ToString() - Add-AzureSqlDatabaseServerFirewallRule -endpoint $endpoint -startIPAddress $startIp -endIPAddress $endIp -serverName $serverName -firewallRuleName $firewallRuleName | Out-Null + Add-AzureSqlDatabaseServerFirewallRule -endpoint $endpoint -startIPAddress $startIp -endIPAddress $endIp -serverName $serverName ` + -firewallRuleName $firewallRuleName -connectedServiceNameARM $connectedServiceNameARM -vstsAccessToken $vstsAccessToken | Out-Null $FirewallSettings.IsConfigured = $true $FirewallSettings.RuleName = $firewallRuleName @@ -57,10 +60,13 @@ function Delete-AzureSqlDatabaseServerFirewallRule { [String] [Parameter(Mandatory = $true)] $firewallRuleName, [String] $isFirewallConfigured, [String] [Parameter(Mandatory = $true)] $deleteFireWallRule, - [Object] [Parameter(Mandatory = $true)] $endpoint) + [Object] [Parameter(Mandatory = $true)] $endpoint, + [string] [Parameter(Mandatory = $false)] $connectedServiceNameARM, + [string] [Parameter(Mandatory = $false)] $vstsAccessToken) if ($deleteFireWallRule -eq "true" -and $isFirewallConfigured -eq "true") { - Remove-AzureSqlDatabaseServerFirewallRule -serverName $serverName -firewallRuleName $firewallRuleName -endpoint $endpoint + Remove-AzureSqlDatabaseServerFirewallRule -serverName $serverName -firewallRuleName $firewallRuleName -endpoint $endpoint ` + -connectedServiceNameARM $connectedServiceNameARM -vstsAccessToken $vstsAccessToken } } diff --git a/Tasks/SqlAzureDacpacDeploymentV1/task.json b/Tasks/SqlAzureDacpacDeploymentV1/task.json index ec1324115001..a7f41ba09bc3 100644 --- a/Tasks/SqlAzureDacpacDeploymentV1/task.json +++ b/Tasks/SqlAzureDacpacDeploymentV1/task.json @@ -16,8 +16,8 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 219, - "Patch": 0 + "Minor": 221, + "Patch": 100 }, "demands": [ "sqlpackage" diff --git a/Tasks/SqlAzureDacpacDeploymentV1/task.loc.json b/Tasks/SqlAzureDacpacDeploymentV1/task.loc.json index c33b18f7dc9e..9c013655b98f 100644 --- a/Tasks/SqlAzureDacpacDeploymentV1/task.loc.json +++ b/Tasks/SqlAzureDacpacDeploymentV1/task.loc.json @@ -16,8 +16,8 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 219, - "Patch": 0 + "Minor": 221, + "Patch": 100 }, "demands": [ "sqlpackage" diff --git a/make-util.js b/make-util.js index ee783a99a5b8..25ec6e4f420a 100644 --- a/make-util.js +++ b/make-util.js @@ -533,12 +533,27 @@ var copyGroup = function (group, sourceRoot, destRoot) { // multiply by culture name (recursive call to self) if (group.dest && group.dest.indexOf('') >= 0) { + var missingCultures = []; cultureNames.forEach(function (cultureName) { - // culture names do not contain any JSON-special characters, so this is OK (albeit a hack) - var localizedGroupJson = JSON.stringify(group).replace(//g, cultureName); - copyGroup(JSON.parse(localizedGroupJson), sourceRoot, destRoot); + try { + // culture names do not contain any JSON-special characters, so this is OK (albeit a hack) + var localizedGroupJson = JSON.stringify(group).replace(//g, cultureName); + copyGroup(JSON.parse(localizedGroupJson), sourceRoot, destRoot); + } + catch (err) { + missingCultures.push(cultureName); + } }); + // some cultures might not be present in certain dlls of TFS so just log and ignore + // fail in case none were present, as this indicates programmer error (or should not be copied at all) + if (missingCultures.length == cultureNames.length) { + throw new Error('Could not find a single culture even though make was instructed to copy them.'); + } + if (missingCultures.length > 0) { + console.log('The following culture names could not be loaded as they do not exist: ' + missingCultures); + } + return; }