Hello folks,
I have this script that was working at 1 point, I modified it to try and collect the information from just some clusters in txt file, but the script never ends. Any idea what Im doing wrong?
$array = @()
$vc = Get-Content 'C:\temp\vSphere\vcs.txt'
$clusters = Get-Content 'C:\temp\vSphere\clusters.txt'
foreach ($v in $vc) {
Connect-VIServer $v -Force
}
$vms = Get-Cluster $clusters | Get-VM -ErrorAction SilentlyContinue
foreach ($cluster in $clusters) {
foreach ($vm in $vms) {
$ds = Get-VM $vm | Select-Object @{N = "Datastore"; E = { Get-Datastore -vm $_ } }
$disks = $vm | Get-ScsiController | Where-Object { $_.BusSharingMode -eq 'Physical' -or $_.BusSharingMode -eq 'Virtual' }
foreach ($disk in $disks) {
$REPORT = New-Object -TypeName PSObject
$REPORT | Add-Member -type NoteProperty -name ClusterName -Value $cluster
$REPORT | Add-Member -type NoteProperty -name Name -Value $vm.Name
$REPORT | Add-Member -type NoteProperty -name VMHost -Value $vm.VMHost
$REPORT | Add-Member -type NoteProperty -name Mode -Value $disk.BusSharingMode
$REPORT | Add-Member -type NoteProperty -name Type -Value 'BusSharing'
$REPORT | Add-Member -type NoteProperty -name Datastore -Value $ds
$array += $REPORT
}
}
}
$array | Export-Csv "C:\temp\Get-SCSIBusSharingVMs-Output.csv"
Thanks for any input!
I don't see why your script would run forever.
But I do see why it could run for a very long time.
In this line, you are getting all the VMs for all the Clusters for all the vCenters.
$vms = Get-Cluster $clusters | Get-VM -ErrorAction SilentlyContinue
Then you have a loop over all the clusters, and for each cluster you loop over all the VMs.
foreach ($cluster in $clusters) {
foreach ($vm in $vms) {
And to add to the execution time, you do another Get-VM with an object that is already the output from a Get-VM.
$ds = Get-VM $vm | Select-Object @{N = "Datastore"; E = { Get-Datastore -vm $_ } }
In $disks you seem to have SCSI Controller objects, not harddisks.
Also not sure what you are doing in the output with the Mode and Type properties?
If I have to guess what you are actually trying to do, I would use code like this.
$vc = Get-Content 'C:\temp\vSphere\vcs.txt'
$clusters = Get-Content 'C:\temp\vSphere\clusters.txt'
foreach ($v in $vc) {
Connect-VIServer $v -Force
}
Get-Cluster -Name $clusters -PipelineVariable cluster |
Get-VM -PipelineVariable vm |
Get-HardDisk -PipelineVariable disk |
Get-ScsiControl -PipelineVariable scsi |
Where-Object {$_.BusSharingMode -in 'Physical','Virtual'} |
ForEach-Object -Process {
New-Object -TypeName PSObject -Property ([ordered]@{
ClusterName = $cluster.Name
Name = $vm.Name
VMHost = $vm.VMHost.Name
Mode = $scsi.BusSharingMode
Datastore = (Get-Datastore -RelatedObject $vm).Name -join '|'
})
} | Export-Csv "C:\temp\Get-SCSIBusSharingVMs-Output.csv"
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
First off, Thanks alot LucD for taking a look.
I do not think that first line is getting all vms for all vcs though.
PS C:\temp\vSphere\Storage> $clusters = Get-Content 'C:\temp\vSphere\clusters.txt'
PS C:\temp\vSphere\Storage> $vms = Get-Cluster $clusters | Get-VM -ErrorAction SilentlyContinue
PS C:\temp\vSphere\Storage> $vms.count
294
We do in fact have 294 machines in those 4 clusters in the cluster.txt list.
And those are the VMs I want to target. I am trying to determine which machines have SCSI bus sharing enabled and what mode.
When I run the version you posted, its only getting the info out of 1 of the clusters, its the 3rd cluster down from the top of the list in clusters.txt, but the data looks accurate for what its pulling.
As far as the mode and type, the mode looks good in the output, i was just trying to add a descriptive column that says 'Bus Sharing', so it reads, 'bus sharing' 'physical' etc.. in output.
Thanks!
That depends what you have in the clsuters.txt file.
Is it the name of 1 cluster per line?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
We do in fact have 294 machines in those 4 clusters in the cluster.txt list.
And those are the VMs I want to target. I am trying to determine which machines have SCSI bus sharing enabled and what mode.
That is correct, but then you loop over all the clusters and use $vms as another loop (inside the clsuter loop).
So if you have 4 clusters, you are going to handles 4 * 294 VMs.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
yes, 4 clusters, 1 per line
That is how my code expects it to be.
But it would amaze me if you only get the results of 1 out of the 4 clusters, unless you changed the code, like the location of the Export_Csv or the location of the Foreach-Object cmdlet.
I tested the code again and it works in my environment.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I did not change anything, I ran again and get the same results but I see loads and loads of this message:
Get-ScsiController : 1/18/2023 9:50:21 AM Get-ScsiController The object 'vim.VirtualMachine:vm-32073' has already been deleted or has not been
completely created
At line:11 char:1
+ Get-ScsiController -PipelineVariable scsi |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-ScsiController], ManagedObjectNotFound
+ FullyQualifiedErrorId : Client20_MoServiceImpl_GetViNetView_ViError,VMware.VimAutomation.ViCore.Cmdlets.Commands.VirtualDevice.GetScsiContro
ller
Get-ScsiController : 1/18/2023 9:50:21 AM Get-ScsiController The object 'vim.VirtualMachine:vm-32073' has already been deleted or has not been
completely created
At line:11 char:1
+ Get-ScsiController -PipelineVariable scsi |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-ScsiController], ManagedObjectNotFound
+ FullyQualifiedErrorId : Client20_MoServiceImpl_GetViNetView_ViError,VMware.VimAutomation.ViCore.Cmdlets.Commands.VirtualDevice.GetScsiContro
ller
so I guess there is an object that is corrupt or something, and its preventing the rest of the output?
Edit - I actually changed the Get-Scsicontrol line to Get-ScsiController because it was barking about that.
Is there a way to exclude the vm-32073 and let it continue?
I added -ErrorAction SilentlyContinue after the get-scsicontroller command, and am running again.
You should try to stop/start your PS session.
That error sometimes happens when VM were deleted while your session was already open
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I tried a few times throughout the day, with new ps sessions, each time I get that error each time with a different vm name though.
I think if I just target each cluster individually and -append the csv, Ill get most of the data.
Any tips on how to add the DS Cluster name in there? I thought something like this would work, but not so much:
DatastoreCluster = (Get-DatastoreCluster -RelatedObject $cluster).Name -join '|'
Thanks!
Boom:
$vc = Get-Content 'C:\temp\vSphere\vcs.txt'
foreach ($v in $vc) {
Connect-VIServer $v -Force
}
Get-Cluster -Name 'clustername' -PipelineVariable cluster |
Get-VM -PipelineVariable vm |
Get-HardDisk -PipelineVariable disk |
Get-ScsiController -PipelineVariable scsi |
Where-Object {$_.BusSharingMode -in 'Physical','Virtual'} |
ForEach-Object -Process {
$dsName = $disk.FileName.Split(']')[0].TrimStart('[')
New-Object -TypeName PSObject -Property ([ordered]@{
ClusterName = $cluster.Name
Name = $vm.Name
VMHost = $vm.VMHost.Name
Mode = $scsi.BusSharingMode
Datastore = (Get-Datastore -RelatedObject $vm).Name -join '|'
DsCluster = (Get-DatastoreCluster -Datastore $dsName).Name
})
} | Export-Csv -Append "C:\temp\Get-SCSIOutput.csv"
I have to run it 4 times to avoid that weird error, but it gets the job done.
Thanks!
Here is my latest version, it takes quite awhile to run, around 44 minutes to go through 294 computers.
I never get those vm errors on this, and it goes through all the clusters, so I only need to run it 1 time:
$vc = Get-Content 'C:\temp\vSphere\vcs.txt'
$clusters = @{
"VC1" = "Cluster1"
"VC2" = "Cluster2"
"VC3" = "Cluster3"
"VC4" = "Cluster4"
}
foreach ($v in $vc) {
Connect-VIServer $v -Force
Get-Cluster -Name $clusters[$v] -PipelineVariable cluster |
Get-VM -PipelineVariable vm |
Get-HardDisk -PipelineVariable disk |
Get-ScsiController -PipelineVariable scsi |
Where-Object { $_.BusSharingMode -in 'Physical', 'Virtual' } |
ForEach-Object -Process {
$dsName = $disk.FileName.Split(']')[0].TrimStart('[')
New-Object -TypeName PSObject -Property ([ordered]@{
ClusterName = $cluster.Name
Name = $vm.Name
VMHost = $vm.VMHost.Name
Mode = $scsi.BusSharingMode
Datastore = (Get-Datastore -RelatedObject $vm).Name -join '|'
DsCluster = (Get-DatastoreCluster -Datastore $dsName).Name
})
} | Export-Csv -Append "C:\temp\Output.csv"
Disconnect-VIServer $v -Force -Confirm:$False
}
