Azure Automation moving blobs hashtable error - azure

I am trying to create a script to move blobs from one container to another after they are processed by another automation process. The code I am using is below.
workflow Move-AttendeeFiles
{
$connectionName = Get-AutomationConnection -Name 'AzureConnection'
$storageAccountName = Get-AutomationVariable -Name 'StorageAccountName'
$storageContainerName = Get-AutomationVariable -Name 'toprocessContainer'
$destContainerName = Get-AutomationVariable -Name 'processedContainer'
Connect-Azure `
-AzureConnectionName $connectionName
inlineScript{
Select-AzureSubscription `
-SubscriptionName $Using:connectionName
Set-AzureSubscription `
-SubscriptionName $Using:connectionName `
-CurrentStorageAccount $Using:storageAccountName
Get-AzureStorageBlob `
-Container $Using:storageContainerName | Start-AzureStorageBlobCopy `
-DestContainer $Using:destContainerName
}
}
It is throwing the below error
Could not retrieve 'System.Collections.Hashtable' connection asset.
Check that you created this first in the Automation service.
I can't seem to get it running and must be staring at it to long. Any help would be much appreciated.

The Connect-Azure runbook takes as a string the connection asset name. You are passing it the connection, itself. Pass the connection name instead.

Joe's answer got my past the Hashtable error but I had some other errors in my code. I wanted to post the working code for everyone.
workflow Move-AttendeeFiles
{
$connectionName = Get-AutomationVariable -Name 'azureConnectionName'
$subId = Get-AutomationVariable -Name 'azureSubscriptionId'
$storageAccountName = Get-AutomationVariable -Name 'StorageAccountName'
$storageContainerName = Get-AutomationVariable -Name 'toprocessContainer'
$destContainerName = Get-AutomationVariable -Name 'processedContainer'
Connect-Azure `
-AzureConnectionName $connectionName
inlineScript{
Select-AzureSubscription `
-SubscriptionName $Using:connectionName
Set-AzureSubscription `
-CurrentStorageAccountName $Using:storageAccountName `
-SubscriptionId $Using:subId
}
}
Note the difference in the Set-AzureSubscription code to use the -SubscriptionId instead of -SubscriptionName as that is not the proper variable.

Related

Azure PowerShell - New-AzWebAppCertificate doesn't return any response

I'm trying to use the New-AzWebAppCertificate cmdlet that creates a new certificate but I want to get the thumbprint after creation.
I have tried the following command that didn't work.
$certificate = New-AzWebAppCertificate -Name $apiName `
-ResourceGroupName $settings.resource `
-WebAppName $apiName `
-HostName $domainName `
-AddBinding -SslState 'SniEnabled' `
Write-Host $certificate.Thumbprint
But $certificate variable is empty.
Also, I've tried adding -OutVariable
New-AzWebAppCertificate -Name $apiName `
-ResourceGroupName $settings.resource `
-WebAppName $apiName `
-HostName $domainName `
-AddBinding -SslState 'SniEnabled' `
-OutVariable out
But still don't work..
If you read the documentation you will find that they are supporting common parameters such as -OutVariable and also the cmdlet produces PSCertificate output. But in fact, none of them are working.

Check if vm has backup enabled, if not enable it (Azure)

I'm building Azure runbook (powershell) which check if vm has backup enabled if it's not, it will enable it. I have problem with adding and building IF statement to make it better.
This is how I do it now and it works, but If vm has backup enabled, runbook will print a lot of red and thats not good. This is part of bigger runbook and those all are running inside on foreach.
$vault= Get-AzureRmRecoveryServicesVault -ResourceGroupName "RGName" -Name "VaultName"
Set-AzureRmRecoveryServicesVaultContext -Vault $vault
Write-Output "Configuring Azure backup to $($vm.Name)"
$policy = Get-AzureRmRecoveryServicesBackupProtectionPolicy -Name "PolicyName"
Enable-AzureRmRecoveryServicesBackupProtection `
-ResourceGroupName $vm.ResourceGroupName `
-Name $vm.Name `
-Policy $policy
Then I wanted to add IF statement there so if backup has been enable on vm, it would just skip it. The below command will print the results of backup ( true or false) but I don't know how to implement that into if statement so if results would be false, it would run the script block and if result would be true, it would just skip and print out $vm.Name has already configured to Azure backup.
Get-AzRecoveryServicesBackupStatus -Name 'VmName' -ResourceGroupName 'RgName' -Type AzureVM
Results of command
if ()
{
$vault= Get-AzureRmRecoveryServicesVault -ResourceGroupName "RgName" -Name "VaultName"
Set-AzureRmRecoveryServicesVaultContext -Vault $vault
Write-Output "Configuring Azure backup to $($vm.Name)"
$policy = Get-AzureRmRecoveryServicesBackupProtectionPolicy -Name "PolicyName"
Enable-AzureRmRecoveryServicesBackupProtection `
-ResourceGroupName $vm.ResourceGroupName `
-Name $vm.Name `
-Policy $policy
}
else {
Write-Output "$vm.Name has already configured to Azure backup"
}
So any tips how to do it? Can I do it somehow like this:
if (Get-AzRecoveryServicesBackupStatus -Name 'vmanme' -ResourceGroupName 'rgname' -Type AzureVM backedup -match false) ?
You can use the command Get-AzRecoveryServicesBackupStatus in the if statement like below to check if is BackedUp or not:
(Get-AzRecoveryServicesBackupStatus -Name 'vmname' -ResourceGroupName 'rgname' -Type AzureVM).BackedUp
If we update your existing code like if backup does not exists it will perform the backup else it will show that Backup is already configured :
if (!(Get-AzRecoveryServicesBackupStatus -Name 'vmname' -ResourceGroupName 'rgname' -Type AzureVM).BackedUp) {
$vault= Get-AzureRmRecoveryServicesVault -ResourceGroupName "RgName" -Name "VaultName"
Set-AzureRmRecoveryServicesVaultContext -Vault $vault
Write-Output "Configuring Azure backup to $($vm.Name)"
$policy = Get-AzureRmRecoveryServicesBackupProtectionPolicy -Name "PolicyName"
Enable-AzureRmRecoveryServicesBackupProtection `
-ResourceGroupName $vm.ResourceGroupName `
-Name $vm.Name `
-Policy $policy
} else {
Write-Output "$vm.Name has already configured to Azure backup"
}

Need powershell script to enable diagnostic logging for Storage account and Key vault

I'm using below script to create a storage account, Key Vault and ADF. I would also like to enable diagnostic logging on both Storage account and Key Vault. Script runs fine and creates the resources however it does not enable the diagnostic logs for KV and Storage account. Would appreciate if you can help.
$subscription="Azure subscription 1"
$rgName = "Test"
$location = "eastus"
$storageaccountName = "tempaccountlogs"
$adfName = "tempdpadf"
$department = "Testtemp"
$kvname = "kvnamAkbt"
$sa = New-AzStorageAccount -ResourceGroupName $rgName -AccountName $storageaccountName -Location $location -SkuName Standard_LRS -Kind BlobStorage -AccessTier Hot -Tag #{department=$department}
$DataFactory = Set-AzDataFactoryV2 -Name $adfName -ResourceGroupName $rgName -Location $location -Tag #{chargecode=$chargeCode;department=$department;environment=$environment;project=$project}
$kv = New-AzKeyVault -VaultName $kvname -ResourceGroupName $rgName -Location $location
set-AzDiagnosticSetting -ResourceId $kv.ResourceId -StorageAccountId $sa.Id -Enabled $true -Categories AuditEvent
set-AzDiagnosticSetting -ResourceId $kv.ResourceId -StorageAccountId $sa.Id -RetentionEnabled $true -RetentionInDays 90
The problem with your script is that it gives error:
A parameter cannot be found that matches parameter name 'Categories'.
You are using "Categories" parameter instead of "Category". If you check this documentation correct parameter is -Category, use this as shown below:
set-AzDiagnosticSetting -ResourceId $kv.ResourceId -StorageAccountId $sa.Id -Enabled $true -Category AuditEvent
set-AzDiagnosticSetting -ResourceId $kv.ResourceId -StorageAccountId $sa.Id -RetentionEnabled $true -RetentionInDays 90
To enable logging for storage account, Please look at this documentation.
$diagname = "storage logs"
$ErrorActionPreference = "SilentlyContinue"
Import-Module -Name Az
Import-Csv "$home\azuresubscription.csv" |`
ForEach-Object{
#CentralLogAnalytics
$workspaceid = "your central logging resource id - exact object"
Select-AzSubscription -Subscription $_.Name
$storageAccounts = Get-AzStorageAccount | Select-Object Id
foreach ($stor in $storageAccounts)
{
Set-AzDiagnosticSetting -Name $diagname -ResourceId $stor.Id -WorkspaceId $workspaceid -Enabled $true
$blobid = -join($stor.id,"/blobServices/default")
$fileid = -join($stor.id, "/fileServices/default")
$queueid = -join($stor.id, "/queueServices/default")
$tableid = -join($stor.id, "/tableServices/default")
$resourcetypeid = #($blobid, $fileid, $queueid, $tableid)
foreach ($item in $resourcetypeid)
{
Set-AzDiagnosticSetting -Name $diagname -ResourceId $item -WorkspaceId $workspaceid -Enabled $true
}
}
}
Prerequisite:
The script expects a list of azure subscription in a CSV file. Putting in CSV is best to easy test in NonProd subscriptions. An object of the subscriptions can also be provided here.
Functionality:
This will enable the metrics for blob, queue, file, and table and at the parent level as well.
You should include -WorkspaceId parameter in the cmd. See reference here.
My example which runs successfully:
set-AzDiagnosticSetting -ResourceId $kv.ResourceId -StorageAccountId $sa.Id -Enabled $true -Category AuditEvent -WorkspaceId {resource id of the Log Analytics workspace}
For how to create a Log Analytics workspace, please refer to Create workspace.
Update:
For how to enable diagnostic logs for ADF, please refer to this sample:
$ws = Get-AzOperationalInsightsWorkspace -Name "testLAW" -ResourceGroupName "test"
$DataFactory = Set-AzDataFactoryV2 -ResourceGroupName "test" -Name "testADF" -Location "WestUS"
set-AzDiagnosticSetting -ResourceId $DataFactory.DataFactoryId -Enabled $true -WorkspaceId $ws.ResourceId

Azure PowerShell Runbook Get Set Az-Disk dynamically

The team is trying to automate a snapshot restore, which was achieved successfully. However I am not able to figure out how to dynamically get the previous disk within the resource group; As well as set the next disk with a new name.
In the code below "AZR-001_OsDisk_7" has to set dynamically to "AZR-001_OsDisk_8" the next time it runs:
$diskConfig = New-AzDiskConfig -Location $snapshot.Location -SourceResourceId $snapshot.Id -CreateOption Copy
$disk = New-AzDisk -Disk $diskConfig -ResourceGroupName "ETD-RFT" -DiskName "AZR-001_OsDisk_7"
$disk1 = Get-AzDisk -ResourceGroupName "ETD-RFT" -Name "AZR-001_OsDisk_7"
Not a final solution, but I have a quick idea. You may use Get-AzDisk -ResourceGroupName 'ResourceGroupName ' to get all the disks. And then you can get the disk name.
As you named the disk with appropriate rule, you may split the name string by _, then you will get a string array which contains all the parts. In this way, you will be able to get the version.
A sample:
$disks = Get-AzDisk -ResourceGroupName JackVS2019
foreach($disk in $disks){
$arr = $disk.Name.Split('_')
Write-Host $arr[2]
}
The output:
1
Then you can generate the new disk name.
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection = Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
$account = Connect-AzAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
Select-AzSubscription -SubscriptionName 101-Prototyping
$vm = Get-AzVM -ResourceGroupName "ETD-RFT" -Name "AZR-101-007-001"
$snapshot = Get-AzSnapshot -ResourceGroupName "ETD-RFT" -SnapshotName "SNAPSHOT-DEC-2019"
$diskConfig = New-AzDiskConfig -Location $snapshot.Location -SourceResourceId $snapshot.Id -CreateOption Copy
$disks = Get-AzDisk -ResourceGroupName "ETD-RFT"
$attached = $disks | Where-Object ManagedBy -ne $null
foreach($disk in $attached)
{
$arr = $disk.Name.Split('_')
$arr[2]
}
$a = $arr[2] -as [int]
$a=$a+1
Write-Host $a
$newname = $arr[0] + "_" + $arr[1] + "_" + $a
$disknew = New-AzDisk -Disk $diskConfig -ResourceGroupName "ETD-RFT" -DiskName $newname
$disk1 = Get-AzDisk -ResourceGroupName "ETD-RFT" -Name $newname
Set-AzVMOSDisk -VM $vm -ManagedDiskId $disk1.Id -Name $disk1.Name
Update-AzVM -ResourceGroupName "ETD-RFT" -VM $vm

Azure Automation Runbook missing mandatory parameters

I'm trying to set a Tag on all virtual machines in my subscription but I keep getting errors when running the Runbook.
The error is the following:
Get-AzureRmVM : Cannot process command because of one or more missing mandatory parameters: ResourceGroupName. At line:30
Here is my Runbook:
$azureConnection = Get-AutomationConnection -Name 'AzureRunAsConnection'
#Authenticate
try {
Clear-Variable -Name params -Force -ErrorAction Ignore
$params = #{
ServicePrincipal = $true
Tenant = $azureConnection.TenantID
ApplicationId = $azureConnection.ApplicationID
CertificateThumbprint = $azureConnection.CertificateThumbprint
}
$null = Add-AzureRmAccount #params
}
catch {
$errorMessage = $_
Throw "Unable to authenticate with error: $errorMessage"
}
# Discovery of all Azure VM's in the current subscription.
$azurevms = Get-AzureRmVM | Select-Object -ExpandProperty Name
Write-Host "Discovering Azure VM's in the following subscription $SubscriptionID Please hold...."
Write-Host "The following VM's have been discovered in subscription $SubscriptionID"
$azurevms
foreach ($azurevm in $azurevms) {
Write-Host "Checking for tag $vmtagname on $azurevm"
$tagRGname = Get-AzureRmVM -Name $azurevm | Select-Object -ExpandProperty ResourceGroupName
$tags = (Get-AzureRmResource -ResourceGroupName $tagRGname -Name $azurevm).Tags
If ($tags.UpdateWindow){
Write-Host "$azurevm already has the tag $vmtagname."
}
else
{
Write-Host "Creating Tag $vmtagname and Value $tagvalue for $azurevm"
$tags.Add($vmtagname,$tagvalue)
Set-AzureRmResource -ResourceGroupName $tagRGname -ResourceName $azurevm -ResourceType Microsoft.Compute/virtualMachines -Tag $tags -Force `
}
}
Write-Host "All tagging is done"
I tried importing the right modules but this doesn't seem to affect the outcome.
Running the same commands in Cloud Shell does work correctly.
I can reproduce your issue, the error was caused by this part Get-AzureRmVM -Name $azurevm, when running this command, the -ResourceGroupName is needed.
You need to use the Az command Get-AzVM -Name $azurevm, it will work.
Running the same commands in Cloud Shell does work correctly.
In Cloud shell, azure essentially uses the new Az module to run your command, you can understand it runs the Enable-AzureRmAlias before the command, you could check that via debug mode.
Get-AzureRmVM -Name joyWindowsVM -debug
To solve your issue completely, I recommend you to use the new Az module, because the AzureRM module was deprecated and will not be updated.
Please follow the steps below.
1.Navigate to your automation account in the portal -> Modules, check if you have imported the modules Az.Accounts, Az.Compute, Az.Resources, if not, go to Browse Gallery -> search and import them.
2.After import successfully, change your script to the one like below, then it should work fine.
$azureConnection = Get-AutomationConnection -Name 'AzureRunAsConnection'
#Authenticate
try {
Clear-Variable -Name params -Force -ErrorAction Ignore
$params = #{
ServicePrincipal = $true
Tenant = $azureConnection.TenantID
ApplicationId = $azureConnection.ApplicationID
CertificateThumbprint = $azureConnection.CertificateThumbprint
}
$null = Connect-AzAccount #params
}
catch {
$errorMessage = $_
Throw "Unable to authenticate with error: $errorMessage"
}
# Discovery of all Azure VM's in the current subscription.
$azurevms = Get-AzVM | Select-Object -ExpandProperty Name
Write-Host "Discovering Azure VM's in the following subscription $SubscriptionID Please hold...."
Write-Host "The following VM's have been discovered in subscription $SubscriptionID"
$azurevms
foreach ($azurevm in $azurevms) {
Write-Host "Checking for tag $vmtagname on $azurevm"
$tagRGname = Get-AzVM -Name $azurevm | Select-Object -ExpandProperty ResourceGroupName
$tags = (Get-AzResource -ResourceGroupName $tagRGname -Name $azurevm).Tags
If ($tags.UpdateWindow){
Write-Host "$azurevm already has the tag $vmtagname."
}
else
{
Write-Host "Creating Tag $vmtagname and Value $tagvalue for $azurevm"
$tags.Add($vmtagname,$tagvalue)
Set-AzResource -ResourceGroupName $tagRGname -ResourceName $azurevm -ResourceType Microsoft.Compute/virtualMachines -Tag $tags -Force `
}
}
Write-Host "All tagging is done"

Resources