Reputation: 11
I'm interested in querying an Azure subscription to provide a Tagging report which indicates the VM Name, Azure Region, and the Tags and Tag Value for each VM.
My current script provides me with the all the data with the exception of the Tag Value for each respective Tag. My output is displaying a result as if a Tag doesn't exist.
Does anyone have any advice on my script? Thanks!
param( [Parameter(Mandatory = $true)] [String] $subscriptionName )
Select-AzSubscription -Subscription $subscriptionName
$allTags = Get-AzTag
$allVMs = Get-AzVM
$vmInformation = @() foreach ($vm in $allVMs) {
$vmInformationObject = New-Object PSObject $vmName = $vm.Name $vmRegion = $vm.Location $vmInformationObject | Add-Member -MemberType NoteProperty -Name "VM_Name" -Value $vmName $vmInformationObject | Add-Member -MemberType NoteProperty -Name "VM_Region" -Value $vmRegion $vm_tags = $vm.tags foreach ($tag in $allTags) { $IfTagExists = $false foreach ($vmtag in $vm_tags) { if ($tag.name -like $vmtag.keys) { $IfTagExists = $true $vmInformationObject | Add-Member -MemberType NoteProperty -Name $tag.Name -Value $vmtag.$($tag.Name) break } } if ($IfTagExists -eq $false) { $vmInformationObject | Add-Member -MemberType NoteProperty -Name $tag.Name -Value "--" } } $vmInformation += $vmInformationObject }
$vmInformation | Export-Csv "path.csv" -NoTypeInformation -Force
Upvotes: 1
Views: 823
Reputation: 1
I am bit late to the party and I would like to mention that if you try to export the results to a CSV file you will have issues. According to Microsoft Export-CSV organizes the file based on the properties of the first object that you submit. If the remaining objects do not have one of the specified properties, the property value of that object is null, as represented by two consecutive commas. If the remaining objects have additional properties, those property values are not included in the file.
Your script will also run slower because you are using the variable $allTags = Get-AzTag instead of filtering only the common tags across all the VMs as you can see in the variable $AllVMsTagKeys in the script below which will do everything that you want and in quicker and cleaner way and will also export the results to a CSV file on your desktop:
$VMs = Get-AzVM -Status
$AllVMsTagKeys = $VMs.Tags.Keys | Sort-Object -Unique
foreach ( $VM in $VMs ) {
$Output = [PSCustomObject]@{
VMName = $VM.Name
VMRegion = $VM.Location
ResourceGroup = $VM.ResourceGroupName
PowerState = $VM.PowerState
}
foreach ( $VMTagKey in $AllVMsTagKeys ) {
Add-Member -InputObject $Output -Force -NotePropertyName $VMTagKey -NotePropertyValue $VM.Tags[$VMTagKey]
}
$Output
$Output | Export-Csv -NoTypeInformation -Append -Path $env:USERPROFILE\Desktop\VMsWithTags.csv
}
Upvotes: 0
Reputation: 25001
The issue here is the comparison statement $tag.name -like $vmtag.keys
. Since the left-hand side value is a scalar and the right-hand side value is a collection or list, you need to use a containment comparison operator. The easiest options are -in
or -contains
.
# Option 1
# Use -in when singular item is on the LHS and collection is on RHS
if ($tag.name -in $vmtag.keys) {
$IfTagExists = $true
$vmInformationObject | Add-Member -MemberType NoteProperty -Name $tag.Name -Value $vmtag.$($tag.Name)
break
}
# Option 2
# Use -contains when singular item is on the RHS and collection is on LHS
if ($vmtag.keys -contains $tag.name) {
$IfTagExists = $true
$vmInformationObject | Add-Member -MemberType NoteProperty -Name $tag.Name -Value $vmtag.$($tag.Name)
break
}
Upvotes: 0