Trying to run a script that will connect to each subscription, and pull the
$azureSubs = Get-AzureRMSubscription
$azureSubs | ForEach-Object {Select-AzureRMSubscription $_ | Out-Null; Get-AzureRMVM | select resourcegroupname, name, licensetype -WarningAction SilentlyContinue}
This works, BUT I'd like to add two more pieces of information: the "OSType" and "VMSize"
If I do a GET-AZURERMVM, in the table for that subscription that the command is run in, the two pieces of information I need are there: VmSize and OsType
However, when I try to add them to the query, the columns are blank.
I believe the VmSize is in the HardwareProfile, and OsType is in the OsProfile, as if I run a "Get-AzureRMVM -name (name) -resourcegroupname (RGname)", then it shows "Hardware Profile: VMSize" and "OSProfile: ComputerName, AdminUsername windowsConfiguration, Secrets"
Ultimate goal is to get the script that will, for each subscription, print results like:
ResourceGroupName | Name | License Type | VMSize | OS Type
TEST_RG | Test_VM | Windows_Server | DS3_v2 | Windows
Test_RG | Test_VM2 | | DS3_v2 | Linux
etc.
Thankful for any help; sorry for such a noob question. Have spent so much time trying to figure this out...
Something like the following would work.
What you were missing mainly was calculated properties.
This is what allow you to perform a select of custom property.
Some notes:
In your code, you used -WarningAction SilentlyContinue on the Select statement. You need to put it on the Get-AzureRMVM CmdLet instead.
This is my opinion but unless you are writing one-liners on purposes, try aerating your code more. It will make it way easier to read, debug and maintain.
This is the code you wrote, modified to include the calculated properties and with the WarningAction parameter set to Get-AzureRMVM instead of the Select statement.
$azureSubs = Get-AzureRMSubscription
$Vms = $azureSubs | ForEach-Object {Select-AzureRMSubscription $_ | Out-Null; Get-AzureRMVM -WarningAction SilentlyContinue | select resourcegroupname, name, licensetype, #{Name="VMSize";Expression={$_.HardwareProfile.VmSize}},#{Name="OsType";Expression={$_.StorageProfile.OsDisk.OsType}}}
$Vms | ft
The same thing, with some progress indication without forcing everything on one line.
$azureSubs = Get-AzureRMSubscription
$Vms = New-Object 'System.Collections.Generic.List[PSObject]'
ForEach ($sub in $azureSubs) {
Select-AzureRMSubscription $sub | Out-Null
Write-Host "Processing Subscription $($sub.Name)".PadRight(50,' ') -ForegroundColor Cyan -NoNewline
[PsObject[]]$items = Get-AzureRMVM -WarningAction SilentlyContinue |
select resourcegroupname,
name,
licensetype,
#{Name="VMSize";Expression={$_.HardwareProfile.VmSize}},
#{Name="OsType";Expression={$_.StorageProfile.OsDisk.OsType}}
Write-Host "($($items.count) retrieved)"
if ($items -ne $null) {
$vms.AddRange($items)
}
}
$vms | Format-Table
You are looking for something like this on the select side
select resourcegroupname, name, licensetype, #{Name="VMSize";Expression={$_.HardwareProfile.VmSize}}, #{Name="OsType";Expression={$_.StorageProfile.OsDisk.OsType}}
Related
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
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.
What im trying to do is the following:
Im getting a list of all VM`s that have some set values such as being in use and NOT having Azure Benefits turned on.
What i have is that i made a tiny script to get all machines within an subscription and select on the basis mentioned above.
What i want to do with that output is do the command Update-azureVM in bulk.
Could someone help me with this ? do i need to export the values to an excel and use that sheet to do a bulk update-AzureVM
here is the code that i have setup at the moment:
$returnObj = #()
$VMs=Get-AzVm -status
foreach ($VM in $VMs)
{
$obj = New-Object psobject -Property #{
"VmSize" = $VM.HardwareProfile.VmSize;
"VmName" = $vm.Name;
"PowerState" = $vm.PowerState;
"License_Type" = $vm.LicenseType;
}
$returnObj += $obj | select VmSize, VmName, PowerState, License_Type
}
$returnObj |
Where-Object{$_.PowerState -ne "VM deallocated"} |
Where-Object{$_.License_Type -ne "Windows_Server"} |
Where-Object{$_.License_Type -ne "Windows_Client"} |
Export-Csv C:\temp\freek.csv
Thank you all in advance!
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
}
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 }
}