How do I normalize this URL in powershell? - azure

I have the following code for Azure key vault resources:
$tempkeyid = (Get-AzKeyVaultKey -VaultName $vaultname -Name $tempkeyname).Id
$tempkeyid = $tempkeyid.Substring(0, $tempkeyid.LastIndexOf('/'))
$tempkeyid
New-AzSynapseWorkspaceKey -ResourceGroupName $resourcegroup -WorkspaceName $workspacename -Name $tempkeyname -EncryptionKeyIdentifier $tempkeyid
Line 2 is there because the key vault returns the versioned identifier but line 4 needs the versionless identifier
The value for $tempkeyid in line 3 is:
https://keyvaultname.vault.azure.net:443/keys/keyname
I get the error:
New-AzSynapseWorkspaceKey: Key Vault URL should be a normalized URL
I've tried to encode and decode the URL with the code below but the encode attempt gets the same error and the decode attempt gets an error that says "Invalid URI: The format of the URI could not be determined". I'm not sure how to normalize it otherwise, or what specifically isn't normalized. The value of $tempkeyid looks correct to me.
$tempkeyid = [System.Web.HttpUtility]::UrlEncode($tempkeyid)
$tempkeyid = [System.Web.HttpUtility]::UrlDecode($tempkeyid)

Encoding is not the same as URI normalisation which refers to expressing the uri in a standard format. (See wikipedia entry). In your case, I would guess it doesn't like the use of the default port (:443). To systematically get a normalised uri, try something like this:
$tempkeyiduri = [System.Uri]($tempkeyid)
$tempkeyid = $tempkeyiduri.AbsoluteUri

Related

Unable to fetch data using powershell as external data source

# main.tf
data "external" "extDateTime" {
program = ["pwsh", "${path.module}/getDateTime.ps1"]
}
output "value" {
value = "${data.external.extDateTime.result.dateTime}"
}
This is the Powershell file getDateTime.ps1 code section
# getDateTime.ps1
$DateTime = Get-Date -Format "yyyyMMddHHmmss"
Write-Output "{""dateTime"": $DateTime}"
Then I run the following command: terraform plan
Error: Unexpected External Program Results with data.external.extDateTime, on main.tf line 26, in data "external" "extDateTime":
26: program = ["Powershell.exe", "${path.module}/getDateTime.ps1"]
The data source received unexpected results after executing the program. Program output must be a JSON encoded map of string keys and string values.
Program: C:\WINDOWS\System32\WindowsPowerShell\v1.0\Powershell.exe
Result Error: invalid character '{' after top-level value
My understanding is the PS script has to return in JSON format but I keep getting the Result Error. Any ideas would be appreciated.
Ensure that the JSON values are correctly formatted as strings (using back ticks to escape double quotes):
$DateTime = Get-Date -Format "yyyyMMddHHmmss"
Write-Output "{`"dateTime`": `"$DateTime`"}"
As per the Terraform docs for the external data source:
The JSON object contains the contents of the query argument and its values will always be strings.
Another way that this can be done is to create a PowerShell custom object and convert it to JSON:
$DateTime = Get-Date -Format "yyyyMMddHHmmss"
$myObject = [PSCustomObject]#{
dateTime = $DateTime
}
ConvertTo-Json $myObject
If you need the output to be a number, you can use the tonumber() function:
output "value" {
value = tonumber(data.external.extDateTime.result.dateTime)
}
I figured out what the issue was. I was running terraform commands in PS 7 (pwsh.exe) but my data.external program was calling PS 5 (powershell.exe). Once I updated to the following: program = ["pwsh.exe", "${path.module}/getDateTime.ps1"] it worked fine. The error message referring to the { was misleading me. Thanks again Cody.

Terraform script empty azurerm automation variable when encrypted flag true

I have a problem when accessing azure automation account variable if the encrypted flag is true. Value is empty. Here are the steps:
Step 1:
resource "azurerm_automation_variable_string" "db-password" {
name = "test-database-password"
resource_group_name = var.rgr-initial
automation_account_name = var.aut-acc-name
value = "bhdc3tSLZjZUcVj8"
encrypted = true
}
Step 2:
data "azurerm_automation_variable_string" "database-password-var" {
name = "test-database-password"
resource_group_name = var.rgr-initial
automation_account_name = var.aut-acc-name
}
Step 3:
password = data.azurerm_automation_variable_string.database-password-var.value
If the flag encrypted is false the I am able to get the value. If it is true and the value is encrypted, it comes empty.
Is there something I am doing wrong?
This is because you can't read encrypted value by design. From Azure docs:
You can't use this [Get-AzAutomationVariable] cmdlet to retrieve the value of an encrypted variable. The only way to do this is by using the internal Get-AutomationVariable cmdlet in a runbook or DSC configuration. For example, to see the value of an encrypted variable, you might create a runbook to get the variable and then write it to the output stream:

Why do I get error "Name or Service not known" when encrypting Azure VM?

I am trying to encrypt a VM in Azure using the following code
$keyVault = Get-AzureRmKeyVault –VaultName “azkeyvaultWestUS” -ResourceGroupName “azkeyvault”;
$diskEncryptionKeyVaultUrl = $keyVault.VaultUri;
$keyVaultResourceId = $keyVault.ResourceId;
$keyEncryptionKeyUrl = (Get-AzureKeyVaultKey –VaultName “azkeyvaultWestUS” –Name “azpavdiskencryption”).Key.kid;
But when I tried to run it, I got the message
Get-AzKeyVaultKey: Name or Service not known
After the instruction ending in .Key.kid
Does anyone know how to fix this?
Thanks in advance.
Try accessing it separately and it should bye key.id
$Key = Add-AzureKeyVaultKey -VaultName "azkeyvaultWestUS" -Name 'azpavdiskencryption'
#get uri
$keyEncryptionKeyUrl = $Key.key.kid

Invoke-AzureRmVMRunCommand parameter passing suddenly fails

Context: Running an Azure Automation Account solution where a caller PS script executes another PS script (executed on a VM) with parameter passing via 'Invoke-AzureRmVMRunCommand'.
Story: I had running a PowerShell (caller) script that executed another (called) PowerShell script on a remote Azure Win VM. That flow ran via an Automation Account schedule every day but suddenly stopped working two days ago because the parameter passing from the caller to the called script is not working anymore. I currently blame the MSFT Azure people for breaking my PRD solution.
Here the caller PS script code for the arguments to pass on:
$hshParams = #{
strSAName = $hshParameters.strStagingSA
strSAAccessKey = $strSAAccessKey
strFileShare = '"' + $strFileShare + '"'
strCopyObjects = $hshParameters.strCopyObjects
strSrcDriveLetter = $strSrcDriveLetter
strDstDriveLetter = $strDstDriveLetter
}
Here the invocaton of the VM-run PS script:
Invoke-AzureRmVMRunCommand -ResourceGroupName $objVM.ResourceGroupName -Name $objVM.Name `
-CommandId 'RunPowerShellScript' -ScriptPath $strRemoteScriptFileNameTmp -Parameter $hshParams
Here the parameter reception code on the VM-run PS script side:
# Parameters
Param (
[string] $strCopyObjects = $null,
[string] $strSAAccessKey = $null,
[string] $strFileShare = $null,
[string] $strSAName = $null,
[string] $strDstDriveLetter = $null,
[string] $strSrcDriveLetter = $null
)
Until two days ago all those six string values were populated properly and according to the argument setup in the hash table '$hshParams':
$strSAAccessKey = 92LO1Q4tuyeiqxxx
$strFileShare = 129xxxa1.file.core.windows.net\solutionfiles
$strSAName = 12xsa1
$strDstDriveLetter = D
$strSrcDriveLetter = Z
$strCopyObjects = AutoTopUp\Application\Live
Problem: Now I see five string values suddenly not being populated anymore with one being garbage, here is what they look like today:
$strSAAccessKey = []
$strFileShare = []
$strSAName = []
$strDstDriveLetter = []
$strSrcDriveLetter = []
$strCopyObjects = AutoTopUp\Application\Live" -strSAAccessKey 92LO1Q4tuyeiqxxx -strFileShare 129xxxa1.file.core.windows.net\solutionfiles -strSAName 12xsa1 -strDstDriveLetter D -strSrcDriveLetter Z
The solution was not touched, it just had been running as per schedule. $Args.Count on the VM-run script returns '2'.
My Question: Anyone with an explanation on this new behaviour? Frustratingly, I did not manage to arrange the parameter passing in a different way as it is all a bit unclear what the proper way of receiving the hash table values would be. The MSFT help page for 'Invoke-AzureRmVMRunCommand' is (of course) not helping here, also did I not find any other clear ways on the parameter passing on SO or Google...
Related question is raised in this MSDN thread; Just sharing this for the benefit of broader audience who might face similar issue.

Is there any problem with my query to get my token?

I'm trying to get an oauth token from my Azure AD using Powershell.
I try to generate my token into a text file to see the result for the 1rst step of my request.
I'm trying to get an Azure Digital Twins token. The constant you see in $resourceId is given by Microsoft to request AzureDigitalTwins.
And here is my script :
# Load ADAL methods
Add-Type -Path ".\MyPath\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
$resultToken = ".\TokenTest.txt"
# Conf here
$aadInstance = "https://login.microsoftonline.com/"
$tenantId = "myTenantID"
$applicationId = "myAppID"
$applicationSecretKey = "myAppSecret"
$resourceId = "0b07f429-9f4b-4714-9392-cc5e8e80c8b0"
# Get an Access Token with ADAL
$authContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext($aadInstance + $tenantId)
$clientCredential = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential($applicationId, $applicationSecretKey)
$authenticationResult = $authContext.AcquireTokenAsync($resourceId, $clientCredential)
($token = $authenticationResult.AccessToken) | Out-File $resultToken
After i run the script my Text file is empty but i get no error.
I use the exact same code in C# to get a token and it's working perfectly but not in Powershell apparently.
Is there a problem with this ?
Thanks for your answers.
Found the answer !
Just needed to add .GetAwaiter().GetResult() to the AcquireTokenAsync method !
$authenticationResult = $authContext.AcquireTokenAsync($resourceId, $clientCredential).GetAwaiter().GetResult()

Resources