FMON's Posts

Hey Tamim- Glad you too are concerned about the kittens.  It has been bad around here for them :smileymischief: Sure I'll be happy to spend some cycles trying to blow up your method.  P... See more...
Hey Tamim- Glad you too are concerned about the kittens.  It has been bad around here for them :smileymischief: Sure I'll be happy to spend some cycles trying to blow up your method.  Probably this weekend or next week sometime.  Unfortunately you are relying on Get-Disk which is 2012 and later and most of my interesting things are still 2008R2.  Have you done much testing in a non-static environment with disks being added and removed? With my method did you get some console errors?  If so what?  If you're not a VMware admin then there are a couple of read privileges you'll need from your VMware people.  The link in my previous post has some details.
Agreed, the parent is nice!
$results = @() foreach ($vm in Get-Vm) {   foreach ($vmHardDisk in $vm | Get-HardDisk)   {   $result = "" | select vmName,NumCpu,MemoryGB,harddiskname,HardDiskCapacityGb   $result.v... See more...
$results = @() foreach ($vm in Get-Vm) {   foreach ($vmHardDisk in $vm | Get-HardDisk)   {   $result = "" | select vmName,NumCpu,MemoryGB,harddiskname,HardDiskCapacityGb   $result.vmName = $vm.Name   $result.NumCpu = $vm.NumCpu   $result.MemoryGB = $vm.MemoryGB   $result.HardDiskName = $vmHardDisk.Name   $result.HardDiskCapacityGb = [System.Math]::Round($vmHardDisk.CapacityGB, 0)   $results += $result   } } $results | ft -AutoSize
Like DZ1 was saying, you can use the credential store.  An alternative way to store your credentials to the credential store is by using the -SaveCredentials switch when calling the Connect-VISer... See more...
Like DZ1 was saying, you can use the credential store.  An alternative way to store your credentials to the credential store is by using the -SaveCredentials switch when calling the Connect-VIServer cmdlet. Connect-VIServer -Server "server1","server2","server3" -Credential $(Get-Credential) -SaveCredentials Keep in mind that any method that uses the credential store is not very secure as the credentials in the credential store are stored on disk using reversible encryption!  Somebody who knows what they're doing can extract the credentials if they gain access to the credential store on disk. LucD's method of storing your creds in a variable is more secure since most of the time that will stay in memory.  Keep in mind that even with Get-Credential, your password is stored in memory with reversible encryption.  Still can be compromised but it's more difficult. Bottom line:  if this is a scheduled thing that needs to run, the credential store is probably (unfortunately) the way to do this.  if this is for an interactive session, then storing in a variable is more secure. Would be nice if this Connect-VIServer could use the session user as previous PowerCLI versions did.  If someone know how please share! EDIT: final thought: if you use the -SaveCredentials switch with Connect-VIServer as shown above, the next time you can connect without specifying -Credential.  For example you can just do this the next time: Connect-VIServer -Server "server1","server2","server3" If your password changes then you'll need to use -SaveCredentials again.
See if this helps: $doathing = $false   #   <Set this to $true to do a thing! set to $false to see what it would do! $vmGroups = @{'Group01'='dc0'               'Group02'='file0'   ... See more...
See if this helps: $doathing = $false   #   <Set this to $true to do a thing! set to $false to see what it would do! $vmGroups = @{'Group01'='dc0'               'Group02'='file0'               'Group03'='fs0'               'Group04'='web'} $i = 1 do {   #decipher what things we are doing things to!   $groupNumber = "{0:D2}" -f [int]$i   $groupName = "Group" + $groupNumber   $groupVms = Get-VM | where {$_.Name -match $vmGroups.$groupName -and $_.powerstate -eq 'PoweredOff'}   #start the Vms!   foreach ($Vm in $groupVms)   {     Write-Host "Starting $($Vm.Name)"     if ($doathing -eq $true){$Vm | Start-VM}else{Write-Host "Didn't start VM $($Vm.Name) because doathing is false!"}   }   #wait for tools on each Vm!   foreach ($Vm in $groupVms)   {     Write-Host "Waiting for tools on $($Vm.Name)"     if ($doathing -eq $true){$Vm | Wait-Tools}else{Write-Host "Didn't wait for tools on VM $($Vm.Name) because doathing is false!"}   }   $i++ } while($i -le $vmGroups.Count)
Kittens die when you match disks via SCSI attributes.  And it's horribly inaccurate. Here is how to do it accurately and without the unnecessary kitten deaths: $vmName = "HolyGrail" ## ... See more...
Kittens die when you match disks via SCSI attributes.  And it's horribly inaccurate. Here is how to do it accurately and without the unnecessary kitten deaths: $vmName = "HolyGrail" ## modification below here not necessary to run $cred = if ($cred){$cred}else{Get-Credential} $win32DiskDrive  = Get-WmiObject -Class Win32_DiskDrive -ComputerName $vmName -Credential $cred $vmHardDisks = Get-VM -Name $vmName | Get-HardDisk $vmDatacenterView = Get-VM -Name $vmName | Get-Datacenter | Get-View $virtualDiskManager = Get-View -Id VirtualDiskManager-virtualDiskManager foreach ($disk in $win32DiskDrive) {   $disk | Add-Member -MemberType NoteProperty -Name AltSerialNumber -Value $null   $diskSerialNumber = $disk.SerialNumber   if ($disk.Model -notmatch 'VMware Virtual disk SCSI Disk Device')   {     if ($diskSerialNumber -match '^\S{12}$'){$diskSerialNumber = ($diskSerialNumber | foreach {[byte[]]$bytes = $_.ToCharArray(); $bytes | foreach {$_.ToString('x2')} }  ) -join ''}     $disk.AltSerialNumber = $diskSerialNumber   } } $results = @() foreach ($vmHardDisk in $vmHardDisks) {   $vmHardDiskUuid = $virtualDiskManager.queryvirtualdiskuuid($vmHardDisk.Filename, $vmDatacenterView.MoRef) | foreach {$_.replace(' ','').replace('-','')}   $windowsDisk = $win32DiskDrive | where {$_.SerialNumber -eq $vmHardDiskUuid}   if (-not $windowsDisk){$windowsDisk = $win32DiskDrive | where {$_.AltSerialNumber -eq $vmHardDisk.ScsiCanonicalName.substring(12,24)}}   $result = "" | select vmName,vmHardDiskDatastore,vmHardDiskVmdk,vmHardDiskName,windowsDiskIndex,windowsDiskSerialNumber,vmHardDiskUuid,windowsDiskAltSerialNumber,vmHardDiskScsiCanonicalName   $result.vmName = $vmName.toupper()   $result.vmHardDiskDatastore = $vmHardDisk.filename.split(']')[0].split('[')[1]   $result.vmHardDiskVmdk = $vmHardDisk.filename.split(']')[1].trim()   $result.vmHardDiskName = $vmHardDisk.Name   $result.windowsDiskIndex = if ($windowsDisk){$windowsDisk.Index}else{"FAILED TO MATCH"}   $result.windowsDiskSerialNumber = if ($windowsDisk){$windowsDisk.SerialNumber}else{"FAILED TO MATCH"}   $result.vmHardDiskUuid = $vmHardDiskUuid   $result.windowsDiskAltSerialNumber = if ($windowsDisk){$windowsDisk.AltSerialNumber}else{"FAILED TO MATCH"}   $result.vmHardDiskScsiCanonicalName = $vmHardDisk.ScsiCanonicalName   $results += $result } $results = $results | sort {[int]$_.vmHardDiskName.split(' ')[2]} $results | ft -AutoSize How the above method works is described here: How to trace a VM disk to a guest disk. :smileycool:
if you just want to keep it from bleeding on your screen when it hits a ds it can't access then replacing the line with this should do it: $searchResult = try{$dsBrowser.SearchDatastoreSubFolder... See more...
if you just want to keep it from bleeding on your screen when it hits a ds it can't access then replacing the line with this should do it: $searchResult = try{$dsBrowser.SearchDatastoreSubFolders($rootPath, $searchSpec)}catch{} Good luck!
You can exclude the $row.SizeBytes from your html by using select-object as shown below in red: $report | select * -exclude SizeBytes | ConvertTo-Html –title "$vCenter - Orphaned VMDK Report" –b... See more...
You can exclude the $row.SizeBytes from your html by using select-object as shown below in red: $report | select * -exclude SizeBytes | ConvertTo-Html –title "$vCenter - Orphaned VMDK Report" –body "<H2>$vCenter - Orphaned VMDK Report</H2>" -head $Header | Out-File $BasePath\$Date\$vCenter-OrphanedVMDKs-$Date.htm Keep in mind, comparing this value to the sum of the converted GB values may result in a rounding difference.
Here is what I was saying about the $orphanSize = 0 foreach ($vCenter in $vCenters) {   $orphanSize = 0   #   <<< since you want to tally orphan size per vcenter, for each vcenter you n... See more...
Here is what I was saying about the $orphanSize = 0 foreach ($vCenter in $vCenters) {   $orphanSize = 0   #   <<< since you want to tally orphan size per vcenter, for each vcenter you need to set it back to zero     $Report= @()   $arrUsedDisks = Get-View -ViewType VirtualMachine | % {$_.Layout} | % {$_.Disk} | % {$_.DiskFile}   Get-View -ViewType Datastore -Property Name,Browser,Host | %{   $ds = $_     $dsBrowser = Get-View $ds.browser     $rootPath = "[" + $ds.Name + "]"     $searchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec -property @{matchPattern="*.vmdk";details=New-Object VMware.Vim.FileQueryFlags -property @{filesize=$true;modification=$true} }     $searchResult = $dsBrowser.SearchDatastoreSubFolders($rootPath, $searchSpec)     foreach ($folder in $searchResult) {       foreach ($fileResult in $folder.File) {         if ($fileResult.Path -match "-flat.vmdk"-and ($fileResult.Modification -lt $DaysOld)) {           if (-not ($arrUsedDisks -contains ($folder.FolderPath + $fileResult.Path))){             $orphanSize += $fileResult.FileSize             $row = "" | Select DataStore, Path, ProbablyOrphanedFile, SizeGB, LastModifiedOn, Host             $row.DataStore = $ds.Name             $row.Path = $folder.FolderPath             $row.ProbablyOrphanedFile = $fileResult.Path             $row.SizeGB = [math]::Round($fileResult.FileSize/1GB,1)             $row.LastModifiedOn = $fileResult.Modification             $row.Host = (Get-View $ds.Host[0].Key).Name             $report += $row           }         }       }     }   }   #also the following 5 lines were originally not part of your foreach vcenter loop   $ovmdkscount = $report.Count   $totalorphanedspace = ([Math]::Round($orphanSize/1GB,1))   $report | ConvertTo-Html –title "$vCenter - Orphaned VMDK Report" –body "<H2>$vCenter - Orphaned VMDK Report</H2>" -head $Header | Out-File $BasePath\$Date\$vCenter-OrphanedVMDKs-$Date.htm   $text = "$vCenter has got $ovmdkscount Orphaned VMDKs - Total Orphaned Space that could be reclaimed is $totalorphanedspace GB"   $text | Out-File $BasePath\$Date\ReportedvCentersStatus.txt -Append -Force } Not sure if that will solve your problem or not but that was a problem. Alternatively you could add this to each of your rows: $row.SizeBytes = $fileResult.FileSize and then calculate the total size at the end: $otherTotalOrphanedSpace = $report | Measure-Object -sum -property SizeBytes | select -expand Sum | foreach { [Math]::Round($_ / 1GB, 1) }
$orphanSize = 0 Does not exist anywhere in the code you pasted.  So as-is it would just keep on growing. Have you considered keeping a size-bytes in the report, and then using measure-o... See more...
$orphanSize = 0 Does not exist anywhere in the code you pasted.  So as-is it would just keep on growing. Have you considered keeping a size-bytes in the report, and then using measure-object -sum to calculate total?
DaHess- I would also be interested in knowing what those links said.  But here's how I'm doing this. Trace the same way as you would for a physical server - by the disk serial number.  (No... See more...
DaHess- I would also be interested in knowing what those links said.  But here's how I'm doing this. Trace the same way as you would for a physical server - by the disk serial number.  (Not LUN ID, although people do trace disks in physical servers that way also.  That's fine most of the time but there can be duplicate LUN IDs.  When that happens you have to use the serial number.  In scripts you should always use the disk serial number.) To find the serial number of the disk in VMware: $virtualDiskManager = Get-View -Id VirtualDiskManager-virtualDiskManager $virtualDiskManager.queryvirtualdiskuuid($vmHardDisk.Filename, $vmDatacenterView.MoRef) RESULT:  60 00 c2 97 68 54 f3 81-ac 91 2e 6a 13 37 a4 fa To find the serial number of the disk in Windows: Get-WmiObject -Class Win32_DiskDrive -ComputerName $vmName -Credential $cred | select -expand SerialNumber #RESULT:  6000c2976854f381ac912e6a1337a4fa The rest should be easy.  And a similar solution in Linux should be possible.  No SCSI madness which is horribly unreliable depending on your environment. The above should work for disks that are not physical mode RDMs.  For those, match the ScsiCanonicalName of the disk in VMware to the serial number of the disk in Windows.  Some hex conversion may be required. More details here, including a PowerShell script, and some caveats and known issues:  How to trace a VM disk to a guest disk.
Look at something I posed a couple days ago:  How to trace a VM disk to a guest disk. That should help you associate VMware disk to OS disk - should work any number of scsi adapters.  The meth... See more...
Look at something I posed a couple days ago:  How to trace a VM disk to a guest disk. That should help you associate VMware disk to OS disk - should work any number of scsi adapters.  The methodology should work for any OS although the script I provided is for Windows. That script does not address your requirement for needing to correlate drive letters to a disk.  But I do have some stuff that will do that in Windows as long as psremoting is enabled on your guest (drive letters don't need psremoting, but mountpoints do).  If you need help with that then post a new question and I'll try to assist this evening.
Try this: $results = @() foreach ($vm in Get-VM) {   foreach ($vmHardDisk in $vm | Get-HardDisk)   {   $out = "" | select Guest,DiskName,DiskFilename,DiskPersistence   $out.Guest... See more...
Try this: $results = @() foreach ($vm in Get-VM) {   foreach ($vmHardDisk in $vm | Get-HardDisk)   {   $out = "" | select Guest,DiskName,DiskFilename,DiskPersistence   $out.Guest = $vm.Name   $out.Diskname = $vmHardDisk.Name   $out.DiskFilename = $vmHardDisk.Filename   $out.DiskPersistence = $vmHardDisk.Persistence   $results += $out   } } $results | ft -AutoSize
Did you see my post from a couple days ago?  Hopefully this is what you've been looking for.  How to trace a VM disk to a guest disk. It describes a method to perform this trace that is more... See more...
Did you see my post from a couple days ago?  Hopefully this is what you've been looking for.  How to trace a VM disk to a guest disk. It describes a method to perform this trace that is more reliable than referencing scsibus and scsitargetid.  The method should work irrespective of guest OS.  PowerShell code for Windows included. Briefly:  for disks that are not physical mode RDM, match VMware disk uuid to serial number of disk in guest.  For physical mode RDM disks, match ScsiCanonicalName to serial number of disk in guest (perhaps with some ASCII to HEX conversion as required in my environment built on NetApp). Not saying this is foolproof but if you find a place where this doesn't work I'd like to hear about it.
How to trace a VM disk to a guest disk No voodoo involved.  If you’re a Linux person then the mechanics of this process should work for you also.  For Windows people I'll include some PowerShe... See more...
How to trace a VM disk to a guest disk No voodoo involved.  If you’re a Linux person then the mechanics of this process should work for you also.  For Windows people I'll include some PowerShell code that should work in Server 2008 and later (requires PowerCLI, and uses WMI). How to trace a disk: IF THE DISK IS NOT a physical mode RDM then simply match the ddb.uuid (virtual disk uuid) of the vmdk to the disk serial number seen in the guest OS.  To get the virtual disk uuid in PowerShell you can call the queryvirtualdiskuuid method of the VirtualDiskManager managed object (example in code).  If you’re not an administrator in VMware then you’ll need System.View privilege, and on every datastore with a disk you want to inspect you’ll need the Datastore.FileManagement privilege. IF THE DISK IS a physical mode RDM then it’s a little trickier but not bad.  In this case the disk serial reported in the guest should display the LUN serial number from the array - NOT the virtual disk uuid of the RDM vmdk.  For these you need to try to match the disk serial of the guest with the last 24 characters of the ScsiCanonicalName of the VM hard disk.  This may or may not be a 1-step process.  The environment where I do things is hosted on NetApp storage, and the LUN serial number from NetApp arrays is in ASCII, so in order to match to the ScsiCanonicalName the LUN serial number first needs to be converted to HEX.  Not sure how other storage vendors are formatting their LUN serial numbers so you may need to tweak.  I’ve coded the script below to hopefully work if you’re on some other array vendor and they either A) use a 12-character ASCII LUN serial number, or B) present a 24-chracter HEX LUN serial number. Works great in my environment but certainly not claiming it will work everywhere.  What I know for sure: Works on Windows VMs with between 1 and 4 SCSI adapters.  (Based on the methodology # SCSI adapters should not matter, nor should their model.) Works with physical mode RDM disks presented from NetApp storage.  (Never tried with virtual mode but don't they should work, possibly minor adjustments required.) 2003 servers don’t work because the Win32_DiskDrive class of WMI didn't provide a SerialNumber property in that version (probably solvable if you must). If anything exists in the guest that masks the disk serial number then this will not work. This won't work somewhere and probably lots of places.  Interested to hear your stories either way. This code is just hacked together.  No error handling - if it bombs it bombs.  Just connect to your VI server (script does NOT do this) and edit $vmName to match the server you want to check. Enjoy :smileymischief: $vmName = "cheezburger" ## modification below here not necessary to run ## #get windows disks via wmi $cred = if ($cred){$cred}else{Get-Credential} $win32DiskDrive  = Get-WmiObject -Class Win32_DiskDrive -ComputerName $vmName -Credential $cred #get vm hard disks and vm datacenter and virtual disk manager via PowerCLI #does not connect to a vi server for you!  you should already be connected to the appropraite vi server. $vmHardDisks = Get-VM -Name $vmName | Get-HardDisk $vmDatacenterView = Get-VM -Name $vmName | Get-Datacenter | Get-View $virtualDiskManager = Get-View -Id VirtualDiskManager-virtualDiskManager #iterates through each windows disk and assign an alternate disk serial number value if not a vmware disk model #required to handle physical mode RDMs, otherwise this should not be needed foreach ($disk in $win32DiskDrive) {   #add a AltSerialNumber NoteProperty and grab the disk serial number   $disk | Add-Member -MemberType NoteProperty -Name AltSerialNumber -Value $null   $diskSerialNumber = $disk.SerialNumber     #if disk is not a VMware disk set the AltSerialNumber property   if ($disk.Model -notmatch 'VMware Virtual disk SCSI Disk Device')   {     #if disk serial number is 12 characters convert it to hex     if ($diskSerialNumber -match '^\S{12}$')     {       $diskSerialNumber = ($diskSerialNumber | foreach {[byte[]]$bytes = $_.ToCharArray(); $bytes | foreach {$_.ToString('x2')} }  ) -join ''     }     $disk.AltSerialNumber = $diskSerialNumber   } } #iterate through each vm hard disk and try to correlate it to a windows disk #and generate some results! $results = @() foreach ($vmHardDisk in $vmHardDisks) {   #get uuid of vm hard disk / and remove spaces and dashes   $vmHardDiskUuid = $virtualDiskManager.queryvirtualdiskuuid($vmHardDisk.Filename, $vmDatacenterView.MoRef) | foreach {$_.replace(' ','').replace('-','')}     #match vm hard disk uuid to windows disk serial number   $windowsDisk = $win32DiskDrive | where {$_.SerialNumber -eq $vmHardDiskUuid}     #if windowsDisk not found then try to match the vm hard disk ScsiCanonicalName to the AltSerialNumber set previously   if (-not $windowsDisk)   {     $windowsDisk = $win32DiskDrive | where {$_.AltSerialNumber -eq $vmHardDisk.ScsiCanonicalName.substring(12,24)}   }     #generate a result   $result = "" | select vmName,vmHardDiskDatastore,vmHardDiskVmdk,vmHardDiskName,windowsDiskIndex,windowsDiskSerialNumber,vmHardDiskUuid,windowsDiskAltSerialNumber,vmHardDiskScsiCanonicalName   $result.vmName = $vmName.toupper()   $result.vmHardDiskDatastore = $vmHardDisk.filename.split(']')[0].split('[')[1]   $result.vmHardDiskVmdk = $vmHardDisk.filename.split(']')[1].trim()   $result.vmHardDiskName = $vmHardDisk.Name   $result.windowsDiskIndex = if ($windowsDisk){$windowsDisk.Index}else{"FAILED TO MATCH"}   $result.windowsDiskSerialNumber = if ($windowsDisk){$windowsDisk.SerialNumber}else{"FAILED TO MATCH"}   $result.vmHardDiskUuid = $vmHardDiskUuid   $result.windowsDiskAltSerialNumber = if ($windowsDisk){$windowsDisk.AltSerialNumber}else{"FAILED TO MATCH"}   $result.vmHardDiskScsiCanonicalName = $vmHardDisk.ScsiCanonicalName   $results += $result } #sort and then output the results $results = $results | sort {[int]$_.vmHardDiskName.split(' ')[2]} $results | ft -AutoSize