2.2 Logische Laufwerke
Beispiel 1: Freien und belegten Speicherplatz anzeigen (WMI-Klasse: Win32_LogicalDisk )
Beispiel 2: Freien und belegten Speicherplatz anzeigen (.Net-Klasse: DriveInfo)
2.3 Freigaben/ Shares
Beispiel 1: Anlage eines neuen Shares
Beispiel 2: Löschen eines Shares
Beispiel 3: Eigenschaften eines Shares
Beispiel 4a: Auf welchem Verzeichnis liegt ein Share (mit "Associators of")
Beispiel 4b: Auf welchem Verzeichnis liegt ein Share (mit "Select *")
Beispiel 5: Welche Shares liegen auf einem Verzeichnis
Beispiel 6: Welche User sind mit einem Share verbunden
Jetzt fehlen noch die Laufwerke, dann haben wir die wichtigsten Objekte des Filesystems durch. Die interessantesten Eigenschaft eines Laufwerks dürfte die Speicherplatzbelegung beziehungsweise der noch verfügbare Speicherplatz sein. Diese Größen lassen sich mit der Powershell und den passenden Klassen auf mehrere Weisen bequem ermitteln.
Beispiel 1: Freien und belegten Speicherplatz anzeigen (WMI-Klasse: Win32_LogicalDisk )
Set-StrictMode -Version "2.0" Clear-Host Gwmi Win32_LogicalDisk | Format-Table ` @{Label="ID"; Expression={"{0}" -f ($_.DeviceID)} Width=3; Align="Right"; }, @{Label=$(" "*2) + "Free in MB"; Expression={"{0:0.0}" -f ($_.Freespace/1MB)}; Width=13; Align="Right"; }, @{Label=$(" "*2) + "Size in MB"; Formatstring="{0:0.0}" Expression= {$_.Size/1MB} Width=13; Align="Right"; } |
#mögliche Ausgabe ID Free in MB Size in MB -- ------------ ------------ C: 80950,3 152624,8 E: 0,0 2414,5 I: 48186,0 51191,4 K: 614301,7 614392,0 S: 78860,5 1638400,0 |
- Der Schlüssel "width" gibt die Feldbreite an, die eine Spalte belegt.
- Der Schüssel "align" oder "alignment" legt die Ausrichtung fest ("left","right","center")
Damit lassen sich jetzt schon ansehlich formatierte Tabellen erstellen
Beispiel 2a: Freien und belegten Speicherplatz anzeigen (System.Io.DriveInfo)
Set-StrictMode -Version "2.0" Clear-Host $Drives=[System.Io.DriveInfo]::GetDrives() $ComputerName = Get-Content Env:ComputerName $Width_0=3 $Width_1=15 $Width_2=20 $Width_3=13 $Width_4=6+$ComputerName.Length #Tabellenüberschrift definieren $HeadLine = "{0,$Width_0} {1,$($Width_1):0.00} {2,$($Width_2):0.00} {3,$($Width_3):0.0%}" -f ` "Drive","Totalsize in GB","TotalFreeSpace in GB","Percentfree" #Tabellenüberschrift ausgeben Write-Host -BackgroundColor DarkYellow -foregroundcolor DarkRed "$HeadLine`n" $Drives | ForEach { If ($_.TotalSize -gt 0){ #damit unverbundene LW nicht angezeigt werden $Drivename = $_.name $Totalsize = $($_.Totalsize)/1GB $TotalFreeSpace = $($_.TotalFreeSpace)/1GB $PercentFree = $($_.TotalFreeSpace)/$($_.Totalsize) #Ausgabe "{0,$Width_0} {1,$($Width_1):0.00} {2,$($Width_2):0.00} {3,$($Width_3):0.0%} " -f ` $Drivename,$Totalsize,$TotalFreeSpace,$PercentFree }Else{ $Drivename = $_.name $ComputerName = Get-Content env:ComputerName "{0}" -f $Drivename } } |
#mögliche Ausgabe |
Beispiel 2b: Freien und belegten Speicherplatz anzeigen (System.Io.DriveInfo)
Im Gegensatz zum obigen Beispiel setze ich eine Datatable als Datenstruktur ein. Ich finde diese Art übersichtlicher und flexibler
Set-StrictMode -Version "2.0" Clear-Host $Drives=[System.Io.DriveInfo]::GetDrives() $Properties = @("DriveName","TotalSize in GB","TotalFreeSpace in GB","PercentFree in %") #Anlage der DataTabelle mit Spalten für jede Property in Properties $DriveTable = New-Object System.Data.DataTable("Drives") $Properties | foreach { $Column = New-Object System.Data.DataColumn($_) $DriveTable.Columns.Add($Column) } ForEach($Drive in $Drives){ $PropertiesInRow = @() Foreach($Property in $Properties) { Switch($Property){ "DriveName" { $Drivename = $Drive.name $PropertiesInRow += $Drive } "TotalSize in GB"{ $Totalsize=$($Drive.Totalsize)/1GB $PropertiesInRow += $TotalSize.ToString("0.#") } "TotalFreeSpace in GB"{ $TotalFreeSpace = $($Drive.TotalFreeSpace)/1GB $PropertiesInRow += $TotalFreeSpace.ToString("0.#") } "PercentFree in %"{ If($TotalFreeSpace -eq 0){ $PercentFree = 0 }Else{ $PercentFree = $TotalFreeSpace/$TotalSize $PropertiesInRow += $PercentFree.ToString("0.##") }#If/Elseif } } #switch }#Foreach($Property in $Properties) $DriveTable.Rows.Add($PropertiesInRow) | Out-Null }#Foreach ($Drive in $Drives) $DriveTable | Format-Table -auto $DriveTable | Export-Csv -Path "c:\temp\drives.csv" -Delimiter ";" |
#mögliche Ausgabe DriveName TotalSize in GB TotalFreeSpace in GB PercentFree in % --------- --------------- -------------------- ---------------- C:\ 136,7 102,1 0,75 D:\ 142,6 142,3 1 E:\ 232,9 231,5 0,99 F:\ 0,1 0,1 0,65 H:\ 0 0 N:\ 1015 1003,9 0,99 |
Kapitel_2.2 Beispiel_2b DriveSpaceps1.ps1.txt
weitere Informationen über DataSets und DataTables findet ihr unter: Datenzugriffe über ADO.Net -> Disconnected Classes
2.3 Freigaben/ Shares
Für die Verwaltung von Freigaben gibt es überraschenderweise keine eigenen cmdlets und auch keine .Net-Klasse. Alle Aufgaben rund um Shares müssen über die WMI-Klasse Win32_Share erledigt werden.
In diesem Kapitel gehe ich nicht so sehr auf die WMI Thema ein. Falls es hier Unklarheiten gibt, sehr euch doch bitte das Kapitel
MSDN: Win32_Share class
Beispiel 1: Anlage eines neuen Shares
Set-StrictMode -Version "2.0" Clear-Host $FolderName = "C:\temp" $ShareName = "TestShare" $ShareType =0 #Standardshare $MaximumAllowed = 8 $Description = "Das ist ein Test" $Password = "" $Access = $Null $Class = Gwmi -query "Select * From Meta_Class Where __CLASS='Win32_Share'" $Return = $Class.Create($FolderName,$ShareName,$ShareType,$MaximumAllowed,$Description,$Password,$Null) Switch($Return.ReturnValue) { 0 {"Share erfolgreich angelegt"} 2 {"Zugriff verweigert"} 8 {"unbekannter Fehler"} 9 {"ungültiger Name"} 22 {"Share exisitiert bereits"} Default {"bitte in der MSDN nach dem ReturnValue von Win32_Share suchen"} } |
#mögliche Ausgaben Share erfolgreich angelegt #Share exisitiert bereits |
Beispiel 2: Löschen eines Shares
Set-StrictMode -Version "2.0" Clear-Host $Computer = "." $Namespace = "Root\cimV2" $ShareName = "'TestShare1'" #Anführungszeichen beachten! $Query = "Select * from Win32_Share Where Name=$ShareName" $Share = Gwmi -query $Query -NameSpace $Namespace -computer $Computer Try{ $Return=$Share.Delete() } Catch{ "Share wahrscheinlich nicht vorhanden" Break } Switch($Return.ReturnValue) { 0 {"Share erfolgreich gelöscht"} 2 {"Zugriff verweigert"} 8 {"unbekannter Fehler"} 9 {"ungültiger Name"} 21 {"Invalid Parameter"} |
#mögliche Ausgaben #Share erfolgreich gelöscht Share wahrscheinlich nicht vorhanden |
Beispiel 3: Eigenschaften eines Shares
MSDN: Win32_Share class
Try{ $Share=[Wmi]"Win32_Share.Name=$ShareName" #$Share=Gwmi -query $Query -NameSpace $Namespace -Computer $Computer #$Share=[Wmi]"\\$Computer\$($NameSpace):Win32_Share.Name=$ShareName" } Catch{ "Vermutlich ist der Share nicht vorhanden" Break } $Share.Properties | ft Name,Value -auto |
#mögliche Ausgabe Name Value ---- ----- AccessMask AllowMaximum False Caption Mein Test Description Mein Test InstallDate MaximumAllowed 15 Name test Path C:\temp\test Status OK Type 0 |
#mögliche Ausgabe Vermutlich ist der Share nicht vorhanden |
Die Bedeutung der Eigenschaften sind in der MSDN unter dem angegebenen Link aufgeführt:
- Accessmask: Ist obsolet und immer leer. Statt dieser Eigenschaft die Mehtode getaccessmask() verwenden
($Instanz.GetAccessMask()).ReturnValue
- AllowMaximum: Bei Windows7 liegt die maximale Anzahl bei 20 Benutzern, bei XP waren es maximal 10 Benutzer. Läßt man diese Einstellung unverändert, besitzt diese Eigenschaft den Wert True , ansonsten False. AllowMaximum steht in Zusammenhang mit MaximumAllowed
- Installdate: kann leer bleiben.
- Type: Interessante Typewerte sind 0 (0x0) oder 2147483648 ((0x80000000). Ersteres entspricht einem normalen Share, letzteres einem administrativen Share wie c$. Falls andere Typen auftreten, so sind diese ebenfalls unter MSDN: Win32_Share class nachzulesen.
Beispiel 4a: Auf welchem Verzeichnis liegt ein Share (Wmi: "Associators of")
Set-StrictMode -Version "2.0" Clear-Host $Computer="." $ShareName="'TestShare'" #Anführungszeichen beachten! $Query="ASSOCIATORS OF {Win32_Share.Name=$ShareName} WHERE AssocClass=Win32_ShareToDirectory" Get-WmiObject -Query $Query -computer $Computer -EA 0 If($? -ne "true"){ "Share vermutlich nicht vorhanden" } #Ausgabe (Get-WmiObject -Query $Query -computer $Computer -EA 0).Name |
#mögliche Ausgabe Hidden : False Archive : True EightDotThreeFileName : c:\temp FileSize : Name : c:\temp Compressed : False Encrypted : False Readable : True c:\temp |
#mögliche Ausgabe #Share vermutlich nicht vorhanden |
Eine nähere Erklärung zu "ASSOCIATORS OF" findet ihr im Kapitel
Beispiel 4b: Auf welchem Verzeichnis liegt ein Share (mit "Select *")
Set-StrictMode -Version "2.0" Clear-Host $Computer="." $ShareName="'TestShare'" #Anführungszeichen beachten! Get-WmiObject -Query "Select * from Win32_Share Where Name=$ShareName" -Computer $computer| Format-Table Name,Path,Description -auto #([WmiSearcher] "Select * from Win32_Share Where Name=$ShareName").get() | Format-Table Name,Path,Description -auto #gleichwertig |
#mögliche Ausgabe Name Path Description ---- ---- ----------- TestShare C:\temp Das ist ein Test |
weitere Möglichkeiten:
Set-StrictMode -Version "2.0" Clear-Host $Computer="." $ShareName="'TestShare'" #Anführungszeichen beachten! [WMI]"Win32_Share.Name=$ShareName" | Format-Table Name,Path,Description -auto [WMI]"\\$Computer\root\cimV2:Win32_Share.Name=$ShareName" | Format-Table Name,Path,Description -auto |
Beispiel 5: Welche Shares liegen auf einem Verzeichnis
Set-StrictMode -Version "2.0" Clear-Host $Computer="." $Path="'C:\\Temp'" #anführungszeichen und Backslashes beachten! $Query="Select * from Win32_Share Where path=$Path" Get-WmiObject -query $Query -computer $Computer| Ft Name, Status, Description, Path -auto |
#mögliche Ausgabe name Status description path ---- ------ ----------- ---- Temp OK C:\Temp 'TestShare' OK Das ist ein Test C:\temp wmi-test OK C:\Temp |
Beispiel 6: Welche User sind mit einem Share verbunden
Set-StrictMode -Version "2.0" Clear-Host $Computer="." #z.B. Domaincontroller $ShareName="'TestShare'" #z.B. Netlogon $Query="ASSOCIATORS OF {Win32_Share.Name=$ShareName} WHERE AssocClass=Win32_ConnectionShare" $ConnectedUsers = @(Get-WmiObject -query $Query -Computer $Computer -EA 0) If($? -ne $True){ "Share vermutlich nicht vorhanden" }Elseif ($ConnectedUsers.Count -eq 0) { "Keine User mit dem share verbunden" }Else{ $ConnectedUsers | Format-Table Username,Computername -auto } |
#mögliche Ausgabe Username Computername -------- ------------ Karl_Napf 192.168.21.76 Heinz_Kunz 192.168.21.10 |
#mögliche Ausgabe Share vermutlich nicht vorhanden |
Interessant sind solche Informationen auch vom "Netlogon"-Share der Domaincontroller. Damit kann man sehen, welche User an der Domäne an diesem Domaincontroller angemeldet sind.