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

 

2.2 Logische Laufwerke

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

Drive Totalsize in GB TotalFreeSpace in GB   Percentfree

C:\           74,53                21,77         29,2%
E:\            1,91                 1,91         99,9%
F:\
I:\            7,50                 4,67         62,3%
N:\          599,99               599,90        100,0%
T:\           19,53                 8,35         42,7%
U:\         2684,50                55,48          2,1%
X:\

 

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 Automation Interfaces -> WMI näher an. In den Skripten zeige ich auch immer wieder mal alternative Möglichkeiten, die zum selben Ergebnis führen.

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 Automation Interfaces -> WMI -> 2.7 Associators Of. Leichter nachvollziehbar ist sicherlich der Weg über eine gewohnte Select-Abfrage, wie im nächsten Beispiel gezeigt.


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.