Hey all - I have over 800 old vmdks that are still mounted to a dozen production VMs. It's rather painful to search through all the disks on the VMs to find the old vmdks and unmount them for deletion.
I know the vmdk names and paths. Is it possible to use vmware powercli to bulk unmount them from whatever VM they are mounted on?
In which format do you have the filenames of those VMDK?
Is that in a CSV?
Are the names of the VMs involved also available in a CSV?
If yes to those questions, you could do something like this
$vmdkNames = @{}
Import-Csv -Path .\vmdknames.csv -UseCulture |
ForEach-Object -Process {
if(-not $vmdkNames.ContainsKey($_.Path)){
$vmdkNames.Add($_.Path,'')
}
}
Import-Csv -Path .\vmnames.csv -UseCulture -PipelineVariable vm |
ForEach-Object -Process {
Get-VM -name $vm.Name | Get-HardDisk -PipelineVariable hd |
ForEach-Object -Process {
if($vmdkNames.Contains($hd.Filename)){
Remove-HardDisk -HardDisk $hd -Confirm:$false
Write-Host "Removed HD $($hd.Filename) from $($vm.Name)"
}
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
In which format do you have the filenames of those VMDK?
Is that in a CSV?
Are the names of the VMs involved also available in a CSV?
If yes to those questions, you could do something like this
$vmdkNames = @{}
Import-Csv -Path .\vmdknames.csv -UseCulture |
ForEach-Object -Process {
if(-not $vmdkNames.ContainsKey($_.Path)){
$vmdkNames.Add($_.Path,'')
}
}
Import-Csv -Path .\vmnames.csv -UseCulture -PipelineVariable vm |
ForEach-Object -Process {
Get-VM -name $vm.Name | Get-HardDisk -PipelineVariable hd |
ForEach-Object -Process {
if($vmdkNames.Contains($hd.Filename)){
Remove-HardDisk -HardDisk $hd -Confirm:$false
Write-Host "Removed HD $($hd.Filename) from $($vm.Name)"
}
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I can export the vm names to a csv. Not sure if I can export the vmdk names to a csv I'll have to check that.
Let me test that and get back to you.
The script you provided doesn't seem to run. No output or errors and the test vm / vmdk are unchanged.
This is what I am running.
$vmdkNames = @{}
Import-Csv -Path C:\Users\user\Downloads\vmdknames.csv -UseCulture |
ForEach-Object -Process {
if(-not $vmdkNames.ContainsKey($_.Path)){
$vmdkNames.Add($_.Path,'')
}
}
Import-Csv -Path C:\Users\user\Downloads\vmnames.csv -UseCulture -PipelineVariable vm |
ForEach-Object -Process {
Get-VM -name $vm.Name | Get-HardDisk -PipelineVariable hd |
ForEach-Object -Process {
if($vmdkNames.Contains($hd.Filename)){
Remove-HardDisk -HardDisk $hd -Confirm:$false
Write-Host "Removed HD $($hd.Filename) from $($vm.Name)"
}
}
}
The one csv file has the vm name and the other file has the vmdk name. I also tried with the vmdk path.
How did you name the columns in those CSV files?
It expects a column named Path in vmdknames.csv and a column Name in vmnames.csv.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
@ITGuy1024
If the aim is to unmount vmdk, and not specifically via powercli you can do all this using a shell script as well. For this you will have to browse the file using "cat /etc/vmware/hostd/vmInventory.xml | grep vmx " and then iterate through vmx files, read them and figure out which scsi controller it is attached to and then set that to false. Post this you will have to reload vmx for it to take effect. Hope this helps!
I can try to help you more if you have any further questions.
I didn't have the column names and I was using the vmdk name rather than the path.
Seems to have worked great on the test I did.
Any suggestion on how to export the vmdk paths to csv?
Thanks for the help!
Do you mean the ones that are disconnected?
PS: strange you mark your copy of my script as the correct answer 🙄
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
The ones still connected. They are all in a certain datastore.
Changed the correct answer to yours. Sorry I was on my phone.
I thought as much 😅
To export the ones still connected, try something like this
$vmdkNames = @{}
$report = @()
Import-Csv -Path .\vmdknames.csv -UseCulture |
ForEach-Object -Process {
if(-not $vmdkNames.ContainsKey($_.Path)){
$vmdkNames.Add($_.Path,'')
}
}
Import-Csv -Path .\vmnames.csv -UseCulture -PipelineVariable vm |
ForEach-Object -Process {
Get-VM -name $vm.Name | Get-HardDisk -PipelineVariable hd |
ForEach-Object -Process {
if($vmdkNames.Contains($hd.Filename)){
Remove-HardDisk -HardDisk $hd -Confirm:$false
Write-Host "Removed HD $($hd.Filename) from $($vm.Name)"
}
else{
$report += '' | Select @{N='VM';E={$vm.Name}},@{N='HD';E={$hd.FileName}}
}
}
}
$report | Export-Csv -Path .\connected-vmdk.csv -NoTypeInformation -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Sorry I mean export the filenames / modified dates from a certain datastore.