I am trying to find a simple way to keep up with the MS Windows Audits. They want to know what version everything is running, so I have a method to do this, but scripting will help me gather things better and a breeze in the future. What I am looking to do is:
1) Is there a way to take a CSV or TSV file with VM names and put VM tags on them, so I can quickly tag x,y,&z with Windows 2012 Standard or something.
2) Can I make a report that would print the VMs by version and total it at the bottom. Something like:
Windows 2012 Standard
x
y
z
Total: 3
Windows 2016 Standard....
This would make my life so much simpler! Thanks for any advice.
This will all depend if you have VMware Tools installed and running on your VMs.
For the tagging you could do something like this
$categoryName = 'OS'
try{
$cat = Get-TagCategory -Name $categoryName -ErrorAction Stop
}
catch{
$cat = New-TagCategory -Name $categoryName -Cardinality Single -EntityType VM
}
Get-VM -Name (Import-Csv -Path $csv -UseCulture).VMName -PipelineVariable vm |
ForEach-Object -Process {
if($vm.Guest.OSFullName){
try{
$tag = Get-Tag -Name $vm.Guest.OSFullName -Category $cat -ErrorAction Stop
}
catch{
$tag = New-Tag -Name $vm.Guest.OSFullName -Category $cat
}
Get-TagAssignment -Entity $vm -Category $cat -ErrorAction SilentlyContinue |
Remove-TagAssignment -Confirm:$false
New-TagAssignment -Entity $vm -Tag $tag -Confirm:$false
}
else{
Write-Host "Could not determine Guest OS for $($vm.Name)"
}
}
For a report you can then do something like this
$cat = Get-TagCategory -Name $categoryName
Get-VM -Name (Import-Csv -Path .\vmnames.csv -UseCulture) -PipelineVariable vm |
Group-Object -Property {$_.Tag.Name} |
Select Name,@{N='Count';E={$_.Group.Count}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I gave this a go, but I got this error:
Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not
null or empty, and then try the command again.
At C:\Users\milleran\Documents\VM-OS.ps1:17 char:14
+ Get-VM -Name (Import-Csv -Path $csv -UseCulture) -PipelineVariable vm ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-VM], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM
The CSV is just a list of few VMs with commas, but that's all.
The script assumes that the CSV looks like this
VMName
vm1
vm2
If your columnname is different (than VMName) you will have to update the propertyname on the Get-VM.
I just updated the code to reflect the VMName column from the example above.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
This is what I get now:
Get-VM | VM with name '@{VMName=Victoria-DC}' was not found using the specified |
filter(s).
sorry for the format there.
I suspect you don't have the VMName property on the Get-VM line
Get-VM -Name (Import-Csv -Path $csv -UseCulture).VMName -PipelineVariable vm |
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
That worked, but the problem I have is its pulling Windows Server 2016 or later, since VMware doesn't see the difference in 2016 & 2019. I can provide a CSV list of the 2019 ones and then just need a script to apply those tags.
If you just need to tag the 2019 ones, use that CSV.
You will have to change the Tag value.
Instead of using $vm.Guest.OSFullName you will need to have a static string with something like 'Windows 2019'.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
That worked great, now I am looking at the reporting piece and what I would like is it to just scan the whole inventory not just the csv at this point and return all OS tags with totals to an html page. I tried to modify the lines but its still looking for variables within the CSV.
This has been a TREMENDOUS help so far though I really appreciate all this!
Try like this
Group-Object -Property {$_.Tag.Name} |
Select Name,@{N='Count';E={$_.Group.Count}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Perfect, can it ignore powered off VMs and VMs in specified folders?
Sure, something like this
$vmToSkip = Get-Folder -Name $folderToSkip | Get-VM |
Select -ExpandProperty Name
Get-TagAssignment -Category OS |
where{$_.Entity.PowerState -eq 'PoweredOn' -and $vmToSkip -notcontains $_.Entity.Name} |
Group-Object -Property {$_.Tag.Name} |
Select Name,@{N='Count';E={$_.Group.Count}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference