irgendwelche vmware Powershell Leute da draußen? Ich hoffe, dass mir jemand helfen kann. Gibt es eine einfache Möglichkeit, mir die Laufwerksbeschriftungen der angehängten Festplatte auf einem Server zu zeigen, und welchen Datenspeicher diese Festplatte hat? Zum Beispiel haben wir einen SQL Server mit dem Mount-Punkt 'SQL01 \ Tlog'. Wie kann ich den Datenspeicher finden, auf dem sich der Datenträger befindet? Dieser Befehl zeigt mir den Pfad jeder Festplatte: (get-vm Computername) .Guest.Disks Dieser Befehl zeigt mir die Datenspeicher auf dem Server: Get-VM Computername | Get-Datastore Wie kann ich das tun, damit ich den Pfad zusammen mit dem Datenspeicher sehen kann?Wie wird der Datenspeicher basierend auf dem Festplattenpfad bestimmt?
Antwort
In der Vergangenheit musste ich die virtuellen Festplatten einer VM zuverlässig mit den Festplatten des Betriebssystems abgleichen. Es ist nicht sicher anzunehmen, dass die erste Festplatte in der Konfiguration einer VM die erste Festplatte im Betriebssystem ist. Bei der folgenden Methode wird zuerst versucht, die Festplatten anhand der Seriennummer abzugleichen. Wenn dies fehlschlägt, versucht es auch, auf der SCSI-Ziel-ID übereinzustimmen. ein Computer, dessen Hostnamen und VM-Name ist $ CN ...
#define the computer & VM name
$CN = 'mycomputer'
#get OS disk information
$GWOsplat = `
@{computername = $CN
class = 'win32_diskdrive'
erroraction = [system.management.automation.actionpreference]::stop}
$OSdisk = get-WMIobject @GWOsplat
#get VM disk information
$GVsplat = `
@{viewtype = ([VMware.VIM.virtualmachine])
filter = @{name="^$CN`$"}
property = @('name','config.hardware.device')
erroraction = [system.management.automation.actionpreference]::stop}
$VM = get-view @GVsplat
$VMdisk = $VM.config.hardware.device | where-object {$_.deviceinfo.label -like 'hard disk*'}
#get the number of SCSI controllers
$controllercount = ($VMdisk.controllerkey | group-object | measure-object).count
#iterate through VM disks
foreach($VMD in $VMdisk)
{
#get VM disk serial number and SCSI target ID
$VMDSN = $VMD.backing.UUID -replace '-',''
$VMDSID = $VMD.unitnumber
#iterate through operating system disks
foreach($OSD in $OSdisk)
{
#get OS disk serial number and SCSI target ID
$OSDSN = $OSD.serialnumber
$OSDSID = $OSD.SCSItargetID
if(($VMDSN -eq $OSDSN) -or (($controllercount -eq 1) -and ($VMDSID -eq $OSDSID)))
{
#matching OSdisk found
#get datastore
$DS = get-datastore -ID $VMD.backing.datastore
#get partitions within OSdisk
$GWOsplat = `
@{computername = $CN
query = "associators of {win32_diskdrive.deviceID='$($OSD.deviceID)'} WHERE resultrole=dependent"
erroraction = [system.management.automation.actionpreference]::stop}
$partition = get-WMIobject @GWOsplat
#get logicaldisks within partitions
foreach($P in $partition)
{
$GWOsplat = `
@{computername = $CN
query = "associators of {win32_diskpartition.deviceID='$($P.deviceID)'} WHERE resultrole=dependent"
erroraction = [system.management.automation.actionpreference]::stop}
$logicaldisk = get-WMIobject @GWOsplat
#output custom object mapping drive letter to datastore
foreach($LD in $logicaldisk)
{
[PScustomobject] `
@{computername = $CN
datastore = $DS
drive = $LD.deviceID}
}
}
break
}
}
}
der Grund, warum ich nur versuchen, SCSI-Ziel-ID-Abgleich
gegeben, wenn es einen einzigen SCSI-Controller ist i nicht eine zuverlässige Art und Weise finden könnte einen SCSI übereinstimmen Controller im Betriebssystem mit dem SCSI-Controller einer VM. Es sollte ein sehr kleiner Nachteil sein, da die meisten Festplatten auf der Seriennummer übereinstimmen und die meisten VMs nicht mehrere SCSI-Controller haben.bearbeiten 1
unten sind 2-Funktionen "Gruppe-volumedisk" und "Gruppe-VMOSdisk". Ich habe sie nicht vollständig kommentiert, aber sie haben einige Kommentare, und sie sind ziemlich einfach.
Gruppe-VMOSdisk verwendet group-volumedisk, um eine Zuordnung der win32_volume-Instanzen eines Computers zu den win32_diskdrive-Instanzen zu erhalten. group-VMOSdisk macht hauptsächlich das, was im ersten Abschnitt dieses Posts war.
function group-volumedisk
{
[cmdletbinding()]
param
(
[parameter(valuefrompipeline=$true,valuefrompipelinebypropertyname=$true)]
[alias('CN')]
[system.string[]]$computername
)
begin
{
new-variable -option constant -name localhost -value ([system.environment]::machinename)
new-variable -option constant -name dbgpfx -value "$localhost`: $($myinvocation.mycommand):"
new-variable -option constant -name dispprop -value @('computername','volume','diskdrive')
new-variable -option constant -name SB -value `
{
begin
{
add-type -typedefinition @"
namespace GDFVNS
{
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct DiskExtent
{
public int DiskNumber;
public System.Int64 StartingOffset;
public System.Int64 ExtentLength;
};
[StructLayout(LayoutKind.Sequential)]
public struct DiskExtents
{
public int numberOfExtents;
public DiskExtent first;
};
public class GDFVname
{
public const uint IoctlVolumeGetVolumeDiskExtents = 0x560000;
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern SafeFileHandle CreateFile(
string lpFileName,
[MarshalAs(UnmanagedType.U4)] System.IO.FileAccess dwDesiredAccess,
[MarshalAs(UnmanagedType.U4)] System.IO.FileShare dwShareMode,
System.IntPtr lpSecurityAttributes,
[MarshalAs(UnmanagedType.U4)] System.IO.FileMode dwCreationDisposition,
[MarshalAs(UnmanagedType.U4)] System.IO.FileAttributes dwFlagsAndAttributes,
System.IntPtr hTemplateFile);
[DllImport("Kernel32.dll", SetLastError = false, CharSet = CharSet.Auto)]
public static extern bool DeviceIoControl(
SafeFileHandle hDevice,
uint IoControlCode,
[MarshalAs(UnmanagedType.AsAny)] [In] object InBuffer,
uint nInBufferSize,
ref DiskExtents OutBuffer,
int nOutBufferSize,
ref uint pBytesReturned,
System.IntPtr Overlapped);
}
}
"@
}
end
{
$volume = get-WMIobject -class win32_volume -filter "drivetype = 3"
foreach($V in $volume)
{
# get the volume's path and format it properly
$path = $V.deviceID
$path = $path.trimstart('\?')
$path = $path.trimend('\')
if($path -notlike '\.\*')
{
$path = "\\.\$path"
}
"$dbgpfx path ($path)" | write-verbose
#get a handle to the volume
$handle = [GDFVNS.GDFVname]::createfile($path,[system.IO.fileaccess]::read,[system.IO.fileshare]::read -bor [system.IO.fileshare]::write,[system.intptr]::zero,[system.IO.filemode]::open,0,[system.intptr]::zero)
"handle ($($handle | out-string))" | write-verbose
if($handle.isinvalid)
{
$lastAPIerr = [system.runtime.interopservices.marshal]::getlastwin32error()
"createfile call failed ($lastAPIerr)" | write-error
continue
}
#get disk extents of the volume pointed to by $handle
$returnbytes = new-object -typename system.Uint32
$DE = new-object -typename GDFVNS.diskextents
$result = [GDFVNS.GDFVname]::DeviceIoControl($handle,[GDFVNS.GDFVname]::IoctlVolumeGetVolumeDiskExtents,[system.intptr]::zero,0,[ref]$DE,[system.runtime.interopservices.marshal]::sizeof($DE),[ref]$returnbytes,[system.intptr]::zero)
"result ($result)" | write-verbose
if($result -eq 0)
{
$lastAPIerr = [system.runtime.interopservices.marshal]::getlastwin32error()
"DeviceIoControl call failed ($lastAPIerr)" | write-error
continue
}
#parse the deviceID of the disk and get its win32_diskdrive
$deviceID = "\\.\PHYSICALDRIVE$($DE.first.DiskNumber)" -replace '\\','\\'
$diskdrive = get-WMIobject -class win32_diskdrive -filter "deviceID = '$deviceID'"
#output custom object mapping the win32_volume to its parent win32_diskdrive
new-object -typename system.management.automation.PSobject -property `
@{computername = $V.PScomputername
volume = $V
diskdrive = $diskdrive}
}
}
}
}
process
{
foreach($CN in $computername)
{
$ICsplat = `
@{computername = $CN
scriptblock = $SB
erroraction = [system.management.automation.actionpreference]::stop}
try
{
invoke-command @ICsplat | select-object -property $dispprop
}
catch
{
"invoke-command failed`n$_" | write-error
continue
}
}
}
}
function group-VMOSdisk
{
[cmdletbinding()]
param
(
[parameter(valuefrompipeline=$true)]
[alias('CN')]
[system.string[]]$computername
)
begin
{
new-variable -option constant -name localhost -value ([system.environment]::machinename)
new-variable -option constant -name dbgpfx -value "$localhost`: $($myinvocation.mycommand):"
}
process
{
foreach($CN in $computername)
{
#get OS disks
$GWOsplat = `
@{computername = $CN
class = 'win32_diskdrive'
erroraction = [system.management.automation.actionpreference]::stop}
$OSdisk = get-WMIobject @GWOsplat
#get mapping of volumes to disks
$voldiskmap = $CN | group-volumedisk
#get VM disks
$GVsplat = `
@{viewtype = ([VMware.VIM.virtualmachine])
filter = @{name="^$CN$"}
erroraction = [system.management.automation.actionpreference]::stop}
$VM = get-view @GVsplat
$VMdisk = $VM.config.hardware.device | where-object {$_.deviceinfo.label -like 'hard disk*'}
#get SCSI controller count
$controllercount = ($VMdisk.controllerkey | group-object | measure-object).count
#iterate through VMdisks
foreach($VMD in $VMdisk)
{
#get the VMdisk serial number and SCSI target ID
$VMDSN = $VMD.backing.UUID -replace '-',''
$VMDSID = $VMD.unitnumber
foreach($OSD in $OSdisk)
{
#get the OSdisk serial number and SCSI target ID
$OSDSN = $OSD.serialnumber
$OSDSID = $OSD.SCSItargetID
if(($VMDSN -eq $OSDSN) -or (($controllercount -eq 1) -and ($VMDSID -eq $OSDSID)))
{
#matching OSdisk found
#get datastore
$DS = get-datastore -ID $VMD.backing.datastore
#get volumes within this OSdisk
$volume = ($voldiskmap | where-object {$_.diskdrive.deviceID -eq $OSD.deviceID}).volume
#output custom object mapping volume to datastore
foreach($V in $volume)
{
[PScustomobject] `
@{computername = $CN
datastore = $DS
volume = $V.name}
}
break
}
}
}
}
}
}
Verbinden Sie sich mit Ihrem vSphere-Server und pipen Sie dann $ CN an die Gruppe-VMOSdisk.
Gruppe-volumedisk wurde aus angepasst: http://www.powershelladmin.com/wiki/PowerShell_Get-MountPointData_Cmdlet
- 1. Wie wird der Wert basierend auf dem Textfeldwert manipuliert?
- 2. (C#) Wie wird der Wert basierend auf dem Namensfeld gespeichert?
- 3. Wie wird die Prozessgröße bestimmt?
- 4. App-Engine-Datenspeicher-Statistiken auf dem Entwicklungsserver
- 5. Wie wird local in ToLocalTime() bestimmt
- 6. Basierend auf dem CPE der Funktion, wie wird die untere Grenze berechnet?
- 7. Wie wird ngClass basierend auf dem Bootstrap-Kollaps gesetzt?
- 8. Wie wird die Paginator-Vorlage basierend auf dem Präfix umgeschaltet?
- 9. Wie wird die Spalte basierend auf dem Zustand hinzugefügt?
- 10. Wie wird Dateiname basierend auf dem Ereignisobjekt in JavaScript abgerufen?
- 11. Wie wird die CSV-Datenquelle basierend auf dem Eingabesteuerelement umgeschaltet?
- 12. Wie die Komponente basierend auf dem Status dynamisch angezeigt wird
- 13. Wie wird eine Eigenschaft basierend auf dem Umgebungswert festgelegt?
- 14. Wie erstelle ich ein Steuerelement, das den Eigenschaftswert basierend auf der gebundenen DataSource bestimmt?
- 15. Wie wird der erweiterte benutzerdefinierte Felder meta_value bestimmt?
- 16. Wie wird der Komponententyp für das varargs-Array bestimmt?
- 17. Wie wird die Reihenfolge der Ausführung für HttpModule bestimmt?
- 18. Wie genau wird der Wert von count (*) in BigQuery bestimmt?
- 19. Wie wird das automatische Blättern von Seiten basierend auf der Darstellung auf dem Bildschirm animiert? (angulare)
- 20. Wie wird der Snapshot basierend auf der Beschreibung gelöscht?
- 21. Wie wird der Tooltip der WPF-Combobox basierend auf dem ausgewählten Wert festgelegt?
- 22. Wie wird der Anzeigetext für Textbereiche basierend auf dem Cookie-Wert beim Laden der Seite festgelegt?
- 23. Verbinden mit dem Google App Engine-Datenspeicher
- 24. Ruhezustand: Reihenfolge der Objekte basierend auf dem Alter
- 25. Wie man die Option basierend auf der Sammeleigenschaft ausgewählt wird
- 26. Wie wird ein Bildpfad basierend auf der Bildschirmbreite geändert?
- 27. Wie wird bestimmt, ob XMLHttpRequest oder XDomainRequest verwendet wird?
- 28. RxJs: Wie Schleife basierend auf dem Zustand der Observablen?
- 29. Filterergebnis basierend auf dem Spaltenwert
- 30. Filtersäule basierend auf dem Datumsbereich
cwr Danke für die Hilfe. Ich habe Ihr Skript gegen einen SQL-Server ausgeführt, den ich habe, beide Laufwerkbuchstaben, C und E. Allerdings haben wir mehrere Mount-Punkte unter E, die sich auf einer eigenen Festplatte befinden. Wie kann ich dieses Skript modifizieren, um Mount-Punkte zu berücksichtigen? Danke im Voraus. – Bill
bearbeitet ursprünglichen Beitrag mit Funktionen zur Unterstützung von Festplatten in Ordnern montiert – cwr