Powershell to Automate AKS Version Upgrade - azure

I'm totally new to powershell, trying to automate the aks cluster upgradation based upon the current version and checking the available versions then update one by one using azure powershell. Here is the code i tried, but getting the following error, so it did not work:
Param
(
[Parameter(Mandatory=$true)]
[String]
$AKSName
)
Connect-AzAccount -Identity > $null
Set-AzContext -SubscriptionId "id" > $null
$AKsResourceGroup= Get-AzResource -Name $AKSName | foreach {$_.ResourceGroupName}
$AKsLocation= Get-AzResource -Name $AKSName | foreach {$_.Location}
#Check Current Version Of Cluster
$CurrentVersion = Get-AzAksCluster -ResourceGroupName $AKsResourceGroup -Name $AKSName | select -ExpandProperty KubernetesVersion -WarningAction Ignore
"The CurrentVersion is $CurrentVersion" | ConvertTo-Json
#Check the availability versions to upgrade
$Versions = Get-AzAksVersion -Location $AKsLocation | where-Object {($_.OrchestratorVersion -gt $CurrentVersion) -and ($_.IsPreview -ne 'True')} | foreach {$_.OrchestratorVersion} -WarningAction Ignore
"These are the available versions $Versions" | ConvertTo-Json
#AKS Upgrade
Set-AzAksCluster -ResourceGroupName $AKsResourceGroup -Name $AKSName -KubernetesVersion $Versions
#To check the status of AKS
Get-AzAksCluster -ResourceGroupName $AKsResourceGroup -Name $AKSName | Format-Table -Property Name, Location, KubernetesVersion, ProvisioningState
the output
"The CurrentVersion is 1.23.8"
"These are the available versions 1.24.3 1.24.6"
Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'KubernetesVersion'. Specified method is not supported. ---> System.NotSupportedException: Specified method is not supported.
unable to upgrade the kubernetesversion- need to upgrade to next version based on var CurrentVersion

I tried to rework the same issue in my environment and got the below results
Declared the variable like aks name, resource group and the location using below commands
I run the same command but got the same error as mentioned below
To check the current version of the cluster
$CurrentVersion = Get-AzAksCluster -ResourceGroupName $AKsResourceGroup -Name $AKSName | select -ExpandProperty KubernetesVersion -WarningAction Ignore
"The CurrentVersion is $CurrentVersion" | ConvertTo-Json
To check the availability version to upgrade
$Versions = Get-AzAksVersion -Location $AKsLocation | where-Object {($_.OrchestratorVersion -gt $CurrentVersion) -and ($_.IsPreview -ne 'True')} | foreach {$_.OrchestratorVersion} -WarningAction Ignore
"These are the available versions $Versions" | ConvertTo-Json
Here I am able to see 3 versions to upgrade, at a time we cannot upgrade the 3 versions and we cannot directly upgrade the 1st to 3rd version
Hence we are getting the error. To resolve this issue, I have split and converted into final version
$attempt3 =$versions.Replace(' ', ' , ')
$attempt3=$attempt3.replace(' " ' , " ")
$attempt3=$attempt3.replace(" ' "," ")
#for upgrading the latest version
$finalversion=$attempt3.Split(",")[o]
Set-AzAksCluster -ResourceGroupName $AKsResourceGroup -Name $AKSName -KubernetesVersion $finalversion
I am able to see the latest version which I have upgraded
Get-AzAksCluster -ResourceGroupName $AKsResourceGroup -Name $AKSName | Format-Table -Property Name, Location, KubernetesVersion, ProvisioningState

Related

Unable to update Azure Network Security Group using az cli

I am attempting to update a Network Security Group (SourceAddressPrefixes) via the cli. To begin, it appears that the az cmdlet Set-AzNetworkSecurityRuleConfig is broke; the output from the command states that it's succeeded but no change actually occurs to the NSG. Others have complained about this but no fix from MSFT yet.
With that said, I have tried a workaround method which saves the NSG in a variable, sets the SourceAddressPrefixes, and updates the NSG after:
$SaContext = (Get-AzStorageAccount -ResourceGroupName $RGName -Name $SAName).Context
$table = (Get-AzStorageTable -Name $TableName -Context $SaContext).CloudTable
$IPs = (Get-AzTableRow -Table $table).IP
$IPs = '"{0}"' -f ($IPs -join '","') # Updates the IPs to be double-quoted and separated by commas
$NSG = Get-AzNetworkSecurityGroup -ResourceGroupName $MyResourceGroup -Name $NSGName
($nsg.SecurityRules | Where-Object {$_.Name -eq 'HTTPS'}).SourceAddressPrefix = $IPList
$NSG | Set-AzNetworkSecurityGroup | Get-AzNetworkSecurityRuleConfig -Name $RuleName | Format-Table -AutoSize
The issue with the code above is that the cmdlet Set-AzNetworkSecurityGroup will not except value type system.string. It will only accept System.Collections.Generic.List[System.String]. Due to that I perform the following:
$IPList = New-Object System.Collections.Generic.List[string]
$IPList.Add($IPs)
Now, the previous Set-AzNetworkSecurityGroup accepts the array but now the command fails because the array values aren't double-quoted with a comma to separate them. Not sure what to do at this point.
Actual error messages below:
Cannot convert the (ip addresses here) value of type [system.string] to type "Systems.Collections.Generic.IList[System.String]
And once I convert my variable(array) to match that requirement the error is:
nsgRule has invalid Address Prefix. Value Provided (ip addresses here) statuscode:400 which i'm sure is because converting the array removes the double-quotes & commas.
If you want to update the Source Address Prefix of one Network Security Group rule, its value should be like
192.162.0.1
192.162.1.1
...
For example
$nsg= Get-AzNetworkSecurityGroup -Name $NSGName -ResourceGroupName $MyResourceGroup
$IPList = New-Object System.Collections.Generic.List[string]
$IPList.Add("192.162.0.1")
$IPList.Add("192.162.1.1")
($nsg.SecurityRules | Where-Object {$_.Name -eq 'Port_8080'}).SourceAddressPrefix =$IPList
$nsg|Set-AzNetworkSecurityGroup | Get-AzNetworkSecurityRuleConfig -Name "Port_8080" | Format-Table -AutoSize

Get Azure resource using filters

i'm trying to use Powershell to query my Storage Accounts by using name filter
I have tried these commands (and their variants) but have not still managed to get this working.
Get-AzStorageAccount | where -FilterScript {($_.ResourceType -eq "storageAccounts") -and ($_.StorageAccountName -contains "Prod") }
Get-AzResource -ResourceType Microsoft.Storage/storageAccounts | Get-AzResource -Name Prod* | ft
Any tips because I'm a bit lost. My goal would be that command / script would print out e.g all Storage Accounts which contains Prod in their name.
You can use Where-Object and -match to filter here:
Get-AzStorageAccount | Where-Object {$_.StorageAccountName -match 'prod'}
Or using -like:
Get-AzStorageAccount | Where-Object {$_.StorageAccountName -like '*prod*'}
If you really want to use Get-AzResource, then you need to filter by the Microsoft.Storage/storageAccounts resource type:
Get-AzResource -ResourceType "Microsoft.Storage/storageAccounts" | Where-Object {$_.Name -match 'prod'}
You can have a look at Matching Operators from about_comparison_operators for more information.

Azure Route Table Modification With Powershell

We have over 20 route tables that we need to be able to quickly modify.
We have 2 NVAs that could act as the next hop but we are not able to find the correct solution.
We are stuck at this:
$groupname = Get-AzResourceGroup | Out-GridView –PassThru | Select -ExpandProperty ResourceGroupName
$rt = Get-AzRouteTable -ResourceGroupName $groupname | Out-GridView -PassThru
$oldroutes = Get-AzRouteTable -ResourceGroupName $groupname | Get-AzRouteConfig | Where-Object -Property NextHopIpAddress -Like 1.1.1.1 | Select -ExpandProperty Name
foreach ($oldroutes in $oldroutes)
{
Set-AzRouteConfig -RouteTable $rt -Name $oldroute -NextHopIpAddress 2.2.2.2 | Set-AzRoutetable }
This works to the part that is able to go through all Route Tables and identify all routes that have next hop as 1.1.1.1 and store them in a variable called $oldroutes and only selecting the route Name which is needed by the Set-AZRouteConfig command.
It runs correct up until the Set part. Instead of Modifying it just sets the NextHopIpAddress as 2.2.2.2 and deletes all other values, so when we try to commit the changes we get an error.
Set-AzRoutetable : Address prefix string for resource ...... cannot be null
Has anyone done this or are we missing anything maybe?
Thank you in advance!
I can reproduce your issue, when using Set-AzRouteConfig | Set-AzRoutetable , the parameter -AddressPrefix is needed, if you don't want change it, you could specify it with the original one. And if you want to set -NextHopIpAddress, you need to specify the -NextHopType only with VirtualAppliance. And this part $oldroutes in $oldroutes is also has a mistake, it should be $oldroute in $oldroutes.
So in summary, your script should be like below.
$groupname = Get-AzResourceGroup | Out-GridView –PassThru | Select -ExpandProperty ResourceGroupName
$rt = Get-AzRouteTable -ResourceGroupName $groupname | Out-GridView -PassThru
$oldroutes = Get-AzRouteTable -ResourceGroupName $groupname | Get-AzRouteConfig | Where-Object -Property NextHopIpAddress -Like 1.1.1.1
foreach ($oldroute in $oldroutes)
{
Set-AzRouteConfig -RouteTable $rt -Name $oldroute.Name -AddressPrefix $oldroute.AddressPrefix -NextHopType VirtualAppliance -NextHopIpAddress 2.2.2.2 | Set-AzRoutetable
}

How to delete managed disk snapshot every 10 minutes

I have the below script which I am using in order to delete snapshot older then 10 minutes and retain the snapshot that are not older then 10minutes, I have the below script but its not working as it suppose to, can anyone tell me whats being going wrong?
foreach($snapname in $snapshotnames)
{
Get-AzureRmSnapshot -ResourceGroupName $rg -SnapshotName $snapname |?{$_.Name -Like "*-Server1*"} | ?{($_.TimeCreated).ToString('yyyyMMdd') -lt ([datetime]::Now.AddMinutes(-10).tostring('yyyymmdd'))} | remove-azurermsnapshot -force
}
You should use [datetime]::UtcNow instead of [datetime]::Now and not use .tostring('yyyymmdd').
So your command should be:
foreach($snapname in $snapshotnames)
{
Get-AzureRmSnapshot -ResourceGroupName $rg -SnapshotName $snapname | ?{$_.Name -Like "*-Server1*"} | ?{($_.TimeCreated) -lt ([datetime]::UtcNow.AddMinutes(-10))} | remove-azurermsnapshot -force
}
My specific test command:
Get-AzureRmSnapshot -ResourceGroupName "<ResourceGroupName>" -SnapshotName "<SnapshotName>" | ?{($_.TimeCreated) -lt ([datetime]::UtcNow.AddMinutes(-10))} | remove-azurermsnapshot -force
Result screenshot:

How to get all Azure Resources without tags in a Azure Resource Group

In my Azure dev/test lab (DTL), there are many resources which were not tagged. How can I get a list of all untagged resources under DTL/resource group?
Here's a simple PowerShell loop to get untagged resources.
$resources = Get-AzureRmResource
foreach($resource in $resources)
{
if ($resource.Tags -eq $null)
{
echo $resource.Name, $resource.ResourceType
}
}
Other ways to query this information and also set tags programmatically or as part of resource deployments are described here.
If you want to avoid the situation of ending up with untagged resources, you could enforce a customized policy that all resources should have a value for a particular tag.
Here is the idiomatic PowerShell to supplement #huysmania's answer which is expressed in procedural language mindset (and updated for the new PowerShell Az cmdlets):
Get-AzResource | Where-Object Tags -eq $null | Select-Object -Property Name, ResourceType
and the terse (alias) form:
Get-AzResource | ? Tags -eq $null | select Name, ResourceType
I usually just run this command to output a table of untagged resources using Get-AzResource. It filters Azure resources with tags that are $null or empty using Where-Object.
Get-AzResource `
| Where-Object {$null -eq $_.Tags -or $_.Tags.Count -eq 0} `
| Format-Table -AutoSize
If you want to list untagged resources for a specific resource group, you can just add the -ResourceGroupName switch to Get-AzResource.
$resourceGroupName = "My Resource Group"
Get-AzResource -ResourceGroupName $resourceGroupName `
| Where-Object {$null -eq $_.Tags -or $_.Tags.Count -eq 0} `
| Format-Table -AutoSize
Note: The above uses the newer Azure PowerShell Az module, which is replacement for AzureRM.
<#Bellow is PowerShell script to locate untagged resources -
you may change the script out put as per your requirement.
Hope must be helpful. Thanks!#>
Write-Host "List all resource where Tag value is not Set"
Write-Host "********************************************"
#Fetch all resource details
$resources=get-AzureRmResource
foreach ($resource in $resources) {
$tagcount=(get-AzureRmResource | where-object {$_.Name -match $resource.Name}).Tags.count
if($tagcount -eq 0) {
Write-Host "Resource Name - "$resource.Name
Write-Host "Resource Type and RG Name : " $resource.resourcetype " & " $resource.resourcegroupname "`n"
}
}
This link has the solution for this question. It beautifully explains assigning and querying tags using powershell.
$resourceGroupName = 'InternalReportingRGDev'
$azureRGInfo = Get-AzureRmResourceGroup -Name $resourceGroupName
foreach ($item in $azureRGInfo)
{
Find-AzureRmResource -ResourceGroupNameEquals $item.ResourceGroupName | ForEach-Object {Set-AzureRmResource -ResourceId $PSItem.ResourceId -Tag $item.Tags -Force }
}

Resources