Was ist das Ergebnis des folgenden Skriptes
[int]$a = -7 [int]$b = 3 Write-Host($a/$b) Write-Host([int]($a/$b)) -2,3333 -2
Das Ergebnis der Division zweier Ganzzahlen ist ein Wert vom Typ double. Erst durch das Casten des Wertes in ein Integer wird eine Ganzzahl als Ergebnis zurückgegeben. Bei Komma 5 wird der Integer-Wert auf die höhere Zahl aufgerundet
Welche Zeichen sind für das Erstellen eines Variablennamens möglich. Recherchieren Sie falls notwendig auch im Internet
You can use virtually any variable name you choose, names are not case sensitive. Note: there are illegal characters such as; ! @ # % & , . and spaces. PowerShell will throw an error if you use an illegal character.
I stated virtually any name as PowerShell does have a set of keywords that are reserved and cannot be used as variable names:
- break
- continue
- do
- else
- elseif
- filter
- foreach
- function
- if
- in
- return
- switch
- until
- where
- while
Welchen Unterschied macht es, ob sie als Kennzeichen für einen String das Zeichen ” oder das Zeichen ‘ einsetzen.
Beide Zeichen sind erlaubt, beim ‘-Zeichen wird nicht interpoliert. Eine Variable innerhalb des Strings würde nicht mit dem Wert dargestellt. Beispiel:
$Teacher1 = "Steinam" $TEacher2 = 'Sierl' $ausgabe = "Hallo $Teacher1 " $ausgabe2 = "Hallo $Teacher2 "
Wie kann man erfahren, welcher Datentyp eine Variable bzw. ein Wert hat
(42).GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Int32 System.ValueType (-7/3).GetType() (9/3).GetType()
Die Werte müssen erst berechnet werden. Dies wird durch die Klammerung erreicht.
Sie möchten einen String als Datum weiterverwenden, falls er ein reguläres Datum ist.
[DateTime]"03/13/1964"
Welche Vorteile hat das Casten eines Strings in ein DateTime-Objekt
Man verfügt anschließend über die Methoden des DateTime-Objektes, was eine Weiterbearbeitung häufig einfacher macht, z.B. bei Datumsberechnungen.
$result = ((get-date).subtract([DateTime]"03/13/1964")) ($result.Days/366).gettype()
Welche Variablen sind beim Start von Powershell bereits vorhanden ? Wie kann man sie sichtbar machen
dir variable:zeigt alle in der PS-Sitzung verwendeten bzw. bereits vorhandenen Variablen
Folgender Quellcode ist vorhanden
$a = "Hello" $b = 123
- Bestimmen Sie die Länge des Wertes der Variable $a
- An welcher Stelle im String kommt der Buchstabe “e” vor
- Tauschen Sie den Buchstaben ‘e’ durch den Buchstaben ‘a’
$a.Length $a.IndexOf("e") $a.Replace("e", "a")
Einfach ein test
Schreiben Sie eine Funktion, die als Parameter einen Pfad erwartet und anschließend den Inhalt des Pfades ausgibt
function listDirectory($pfad) { cd $pfad Dir $pfad |Out-File C:\temp\Ausgabe.txt }
Wie überprüfen Sie, ob ein Array einen bestimmten Wert enthält
Mit Hilfe des -contains - Operators
Wie überprüfen Sie, ob zwei Arrays gleich sind
Folgende Funktion überprüft zwei Arrays auf Gleichheit
function AreArraysEqual($a1, $a2) { if ($a1 -isnot [array] -or $a2 -isnot [array]) { throw "Both inputs must be an array" } if ($a1.Rank -ne $a2.Rank) { return $false } if ([System.Object]::ReferenceEquals($a1, $a2)) { return $true } for ($r = 0; $r -lt $a1.Rank; $r++) { if ($a1.GetLength($r) -ne $a2.GetLength($r)) { return $false } } $enum1 = $a1.GetEnumerator() $enum2 = $a2.GetEnumerator() while ($enum1.MoveNext() -and $enum2.MoveNext()) { if ($enum1.Current -ne $enum2.Current) { return $false } } return $true }
Ein String ist eigentlich ein Array aus Elementen des Datentyps CHAR.
$test = "Hello" $test[0].Gettype() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Char System.ValueTypeDie Ansprechen eines einzelnen Elementes ist auch mit $test[1] problemlos möglich. Wie können Sie aber ein einzelnes Element eines bestehenden Strings mit Hilfe der Array-Indiziierung ändern, also etwas so
$integerarray = 1,2,2 $integerarray[2] = 345 # geht $test = "Hello" $test[0] = "F" #FehlermeldungLösung:
Das Umwandeln mit Hilfe der String-Methode ToCharArray() erzeugt einen Array aus CHAR-Elementen, die verändert werden können.
$ergebnis = $test.ToCharArray() $ergebnis[0] = "F"
Überprüfen sie, ob ein bestimmter Wert in einem Array enthalten ist, z.B.
$arrColors = "blue", "red", "green", "yellow", "white", "pink", "orange", "turquoise"Prüfen Sie, ob der Wert “green” enthalten ist
foreach($element in $arrColors) { if($element -eq "green") { Write-Host } else { Write-Host "Not found" } }Es geht natürlich in Powershell auch einfacher
$arrColors = "blue", "red", "green", "yellow", "white", "pink", "orange", "turquoise" $result = $arrColors -contains "green"
Haben wir Elemente, die mit “bl” beginnen
$arrColors = "blue", "red", "green", "yellow", "white", "pink", "orange", "turquoise", "black" $arrColors -like "bl*"
Sortieren sie den obigen Array alphabetisch
$arrColors = "blue", "red", "green", "yellow", "white", "pink", "orange", "turquoise", "black" $arrColors = $arrColors | Sort-Object
Vergleichen Sie die Geschwindigkeit beim Erstellen und Suchen der folgenden Datenstrukturen: Array vs. Hashtable. Welches Ergebnis stellen Sie fest ?
$testarray = @() $testhash = @{} Write-Host "Array anlegen" Measure-Command { for($i = 1; $i -lt 10000;$i++) { $testarray += $i } } Write-Host "Hash anlegen" Measure-Command { for($i = 1; $i -lt 10000;$i++) { $testhash.Add($i, $i) } } Write-Host "Array enthält 9000" Measure-Command{ $testarray -contains 9000 } Write-Host "Hash enthält 9000" Measure-Command{ $testhash.get_Item(9000) }Das Skript erzeugt folgende Ergebnisse auf einem ASUS Netbook (N270, 2 GByte Ram, Windows 7):
Array anlegen ... TotalSeconds : 27,2567811 TotalMilliseconds : 27256,7811 Hash anlegen TotalSeconds : 0,3869414 TotalMilliseconds : 386,9414 Array enthält 9000 ..... TotalSeconds : 0,0359344 TotalMilliseconds : 35,9344 Hash enthält 9000 ... TotalSeconds : 0,0001328 TotalMilliseconds : 0,1328Fazit:
Gerade wenn Listen zur Laufzeit wachsen ist ein Array schon bei kleinen Datenmengen relativ langsam. Auch die Suche innerhalb von kleinen Datenmengen wird über eine Hashtable deutlich beschleunigt.
Sie besitzen eine Textdatei mit Familienname und Loginname der Firmenmitarbeiter. Sie umfasst über 9000 Einträge und soll dazu hergenommen werden, um “vergessene” Loginnamen zu suchen. Überlegen Sie sich, wie Sie diese Textdatei innerhalb von Powershell-Skripten nutzen können.
$fam_login = @{}
Import-Csv user_passwd.csv | ForEach-Object { $fam_login[$_.username] = $_.passwort}
$fam_login
$fam_login["?9d8k6L2"]
$fam_login.GetEnumerator() | select key, value | export-csv .\testexport.csv
$fam_login | export-clixml -path fam_login.xml
$fam2 = import-clixml -path fam_login.xml
Durch die Nutzung der export-clixml und import-clixml - Commandlets werden Dateien im XML-Format geschrieben. Diese machen es einfacher möglich, Metainformationen zu lesen und zu schreiben.
Folgende Noten einer Schulaufgabe sind vorhanden:
2,3,3,2,4,5,4,3,2,1,6,4,3,2,5,4,1,2,3,6,5,4,3,2,1,4,3,2,1,5,4,4,4,3,2,3,4
Lösen Sie mit Hilfe eines Arrays die folgenden Aufgaben:
$noten = 2,3,3,2,4,5,4,3,2,1,6,4,3,2,5,4,1,2,3,6,5,4,3,2,1,4,3,2,1,5,4,4,4,3,2,3,4
Write-Host "Anzahl der Noten: " $noten.count
#Durchschnitt berechnen
$summe = 0
foreach($note in $noten)
{
$summe = $summe + $note
}
$durschnitt = $summe/$noten.Count
#Häufigkeit jeder Note berechnen
#Mit Hilfe eines 2. Arrays;
#Index dient als Notenzahl
#das erste Element(0) bleibt frei
$haeufigkeit = 0,0,0,0,0,0,0
#Schleife hätte man auch in der ersten Lösung
#novch mit reinnehmen können
foreach($note in $noten)
{
$haeufigkeit[$note]+= 1
}
for($i = 1; $i -lt $haeufigkeit.Count;$i++)
{
Write-Host "Note $i = " $haeufigkeit[$i]
#$prozent = 0
$prozent = 100/$noten.Count*$haeufigkeit[$i]
Write-Host "Note $i = " $prozent
}
#Wie viele Noten liegen unter/über dem Schnitt
$zahl = 0
#Ermittelt die Zahl besser als der Durchschnitt
for($i = 1; $i -lt $durschnitt;$i++)
{
$zahl = $haeufigkeit[$i]
}
$besser = $zahl
$schlechter = $noten.Count - $zahl
Write-Host "besser sind $besser"
Write-Host "schlechter sind $schlechter"
#Sortieren der Noten
#Über den Hilfsarray Hauefigkeit
$AusgabeString = "|"
for($i = 1; $i -lt $haeufigkeit.Count; $i++)
{
$AusgabeString += [string]$i * $haeufigkeit[$i] + "|"
}
$AusgabeString
-eq, -ne, -ge, -gt, -lt, -le, -like, -notlike, -match, -notmatch, -contains, -notcontains, -is, -isnot
-and, -or, -xor, -not
Folgende Variablen sind gegeben:
$user = 'steinam' $pass = 'passwort'Formulieren Sie eine Bedingung in Powershell, die gleichzeitig auf einen korrekten Usernamen und Passwort abfragt.
if($user -ieq 'STEINAM' -and $pass -eq 'passwort') { Write-Host "OK" } else { Write-Host "Fehler" }
Falls andere Werte zurückkommen, kann die Rolle nicht eindeutig definiert werden
Erstellen Sie ein Skript, welches die jeweilige Rolle in Textform ausgibt.
$wmi = get-wmiobject win32_computersystem
"computer " + $wmi.name + " is: "
switch ($wmi.domainrole)
{
0 {" Stand alone workstation"}
1 {" Member workstation"}
2 {" Stand alone server"}
3 {" Member server"}
4 {" Back up domain controller"}
5 {" Primary domain controller"}
default {" The role can not be determined"}
}
Drucker auf verschiedenen Betriebssystemen ermitteln
Verschiedene Betriebssysteme nutzen manchmal unterschiedliche WMI Klassen und/oder Eigenschaften, so z.B. Windows XP, Windows 2003 und Windows 2000. Sie wollen die auf diesen Betriebssystemen verwendeten Drucker auflisten und benötigen ein universell einsetzbares Skript. Verwenden Sie ein if-Statement zum Ermitteln der korrekten OS-Version und verwenden Sie den dafür vorgesehenen Code.
Benutzen Sie die WMI-Klasse win32_OperatingSystem zum Ermitteln der OS-Version sowie win32_Printer auf XP und 2003 und win32_PrintJob auf Win2000-Systemen
$strComputer = Read-Host "Printer Report – Enter Computer Name" $OS = Get-WmiObject -Class win32_OperatingSystem -namespace "root\CIMV2" -ComputerName $strComputer # if statement to run code for Windows XP and Windows 2003 Server. if (($OS.Version -eq "5.1.2600") -or ($OS.Version -eq "5.2.3790")) { write-host "Computer Name: " $strComputer #nested if statement if ($OS.Version -eq "5.1.2600") {write-host "OS Version: Windows XP"} elseif ($OS.Version -eq "5.2.3790") {write-host "OS Version: Windows 2003"} $colPrinters = Get-WmiObject -Class win32_Printer -namespace "root\CIMV2" -computerName $strComputer foreach ($objPrinter in $colPrinters) { write-host "Name: " $objPrinter.Name write-host "Description: " $objPrinter.Description write-host } } # if statement to run code for Windows 2000 Server elseif ($OS.Version -eq "5.0.2195") { write-host "Computer Name: " $strComputer write-host "OS Version: Windows 2000 Server" $colPrinters = Get-WmiObject -Class win32_PrintJob -namespace "root\CIMV2" -computername $strComputer foreach ($objPrinter in $colPrinters) { write-host "Name: " $objPrinter.Name write-host "Description: " $objPrinter.Description write-host } } # if OS not identified else {write-host "The OS for: $strComputer is not supported."} write-host "–END OF REPORT–"
Ping
Schreiben Sie eine Programm, welches Ihnen alle per PING erreichbaren Rechner eines Netzes ermittelt. Das Programm soll alle Adressen von 192.168.0.1 bis 192.168.0.255 pingen. Wenn ein PINg erfolgreich war, soll dies als Ausgabe angezeigt werden.
$ping = New-Object System.Net.NetworkInformation.Ping $i = 0 $liste = 1..255 for($y=0;$y -le 255;$y++) { $ip = "192.168.0." + [string]$liste[$y] $Res = $ping.send($ip) if ($Res.Status -eq "Success") { $result = $ip + " = Success" Write-Host $result $y++ } } $Hosts = [string]$y + " Hosts is pingable" Write-Host $Hosts #Eine andere Lösung ist powershell-typischer (per pipeline) $ping = New-Object System.Net.NetworkInformation.Ping $i = 0 1..255 | foreach { $ip = "192.168.0.$_" $Res = $ping.send($ip) if ($Res.Status -eq "Success") { $result = $ip + " = Success" Write-Host $result $i++ } } $Hosts = [string]$i + " Hosts is pingable" Write-Host $Hosts
ZahlenRaten
Erstellen sie ein Skript, welches folgende Aufgabe erfüllt: Es muss eine Meldung anzeigen, in der der Benutzer aufgefordert wird, eine Zahl zwischen 1 und 50 einzugebeenn. Das Skript muss die vom Benutzer eingegebene Zahl mit einer zufällig generierten Zahl vergleichen. Wenn die Zahlen nicht übereinstimmen, muss das Skript eine Meldung anzeigen, in der angegeben wird, ob die geratene Zahl zu hoch oder zu niedrig war, und der Benutzer aufgefordert wird, noch einmal zu raten.
Wenn der Benutzer richtig rät, muss das Skript die Zufallszahl sowie die Anzahl der Rateversuche anzeigen. An diesem Punkt ist das Spiel beendet, das Skript muss also auch beendet werden.
$guesses = 0
$low = 1
$high = 50
$a = New-Object Random
$a = $a.Next($low,$high)
while ($true)
{
$guess = read-host "Enter a number between 1 and 50: "
$guesses++
if ($guess -eq $a)
{
"Random Number: " + $guess
"Number of Guesses: " + $guesses
break
}
elseif ($guess -gt $a)
{
"Too high"
}
else
{
"Too low"
}
}
Dateien kopieren
Diese Skripts sollen folgende Aufgaben ausführen:
- Durchsuchen des Ordners “C:Scripts” und dessen Unterordnern.
- Durchsuchen jedes Ordners nach sämtlichen Textdateien (Dateien mit der Erweiterung .txt) und Prüfen des Erstellungsdatums jeder Datei.
- Kopieren/Verschieben jeder .txt-Datei, die mehr als 10 Tage zuvor erstellt wurde, in den Ordner “C:Old”.
- Ausgeben des Dateinamens (kein vollständiger Pfad, nur Dateiname) jeder kopierten Datei.
- Ausgeben der Anzahl der kopierten Dateien.
foreach ($i in Get-ChildItem C:\Scripts -recurse) { if (($i.CreationTime -lt ($(Get-Date).AddDays(-10))) -and ($i.Extension -eq ".txt")) { #Copy-Item $i.FullName C:\old $i.Name $x = $x + 1 } } "Total Files: " + $x
Fonts finden
$total = 0
$a = get-item "hklm:\\Software\Microsoft\WindowsNT\CurrentVersion\Fonts"
$f = $a.GetValueNames()
foreach ($i in $f)
{
if ($i.contains("TrueType"))
{
$total++
$i
}
}
Schleifen optimieren
Die Ausgabe des folgenden Powershell-Befehls dauert u.U. sehr lange. Verbessern Sie das Statement im Hinblick auf die Auführungsgeschwindigkeit
# Foreach loop lists each element in a collection: Foreach ($element in Dir C:\ -recurse) { $element.name }Lösung: Ersetze Foreach durch das ForEach-Objekt, das die Elemente der Pipeline sofort bearbeiten kann.
# ForEach-Object lists each element in a pipeline: Dir C:\ -recurse | ForEach-Object { $_.name }
Dateien per ftp hochladen
Sie sollen alle Dateien eines zu spezifizierenden Ordners auf einen ftp-server hochladen. Übergeben Sie den Ordner auf der Kommandozeile
#we specify the directory where all files that we want to upload #$Dir="C:/Dir" if(test-path $args[0]) { $Dir=$args[0] #ftp server $ftp = "ftp://ftp.server.com/dir/" $user = "user" $pass = "Pass" $webclient = New-Object System.Net.WebClient $webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass) #list every sql server trace file foreach($item in (dir $Dir "*.trc")){ "Uploading $item..." $uri = New-Object System.Uri($ftp+$item.Name) $webclient.UploadFile($uri, $item.FullName) } }Unter-Windows kann man auch das BitsTransfer-Cmdlet benutzen. Muss mit Import-Module BitsTransfer in die PS geladen werden (PS V. 2.0). Siehe dazu auch http://msdn.microsoft.com/en-us/library/ee663885%28v=VS.85%29.aspx
Übersicht über laufende Dienste
Verschaffen Sie sich einen Überblick über die laufenden Prozesse. Falls die Prozesse einen bestimmten Namen besitzen, stoppen Sie diese Prozesse bzw. geben das Wort “Gefunden <Dienstname> aus.
Erweitern Sie das Skript, indem Sie die laufenden Dienste in eine Datei schreiben, um sie später wie oben bereits geschehen, auszuwerten. Welche Schwierigkeiten können bei diesem Vorhaben auftreten.
Get-Service | ForEach-Object { if($_.ServiceName -match "RpcSs") { Stop-Service $_.ServiceName Write-Host "Gefunden: " $_.Name } } Get-Service | Export-Clixml C:\dienste.xml foreach ($service in Import-Clixml C:\dienste.xml) { if($service.ServiceName -match "RpcSs") { Write-Host "Gefunden: " $service.Name } }
Schätzen der Festplattenauslastung
Wie lange wird der Speicherplatz einer Festplatte ausreichen, wenn ihr Inhalt jeden Monat um ca. 7,5% wächst. Die Platte hat eine Kapazität von 2 TBiT, eine Startbelegung von 100 MBiT
$Zuwachs = 7.5 $FestplatteMax = 2TB $StartKap = 100MB $FestplatteCurKap = $StartKap $i = 0 do { $FestplatteCurKap *= 1 + $Zuwachs/100 $i += 1 Write-Host "Monat: " $i }while($FestplatteCurKap -lt $FestplatteMax) $result = Get-Date $result = $result.AddMonths($i) $result
Berechnung des Notendurchnschnitts und Notenverteilung eines Testes
Ein Test ergab folgende Einzelnoten: 6,3,4,2,1,2,3,4,1,2,3,2,1,3,4,5,3,5,4,3,2,2,2,1,2,3
Berechnen Sie die Anzahl jeder Note sowie den Durchschnitt
Die folgende Lösung setzt in einigen Teilen die Pipeline der Powershell ein. Dies hätte auch durch eine weitere Schleife erledigt werden können. Bei der Zuweisung der Häufigkeiten pro Noten wird ein 2. Array eingesetzt, ders ich pro Indexposition (ab 1) die absolute Zahl der jeweiligen Note merkt. In Indexposition 0 wird später der Durchschnitt abgelegt
$noten_sa1 = 6,3,4,2,1,2,3,4,1,2,3,2,1,3,4,5,3,5,4,3,2,2,2,1,2,3 $notenwerte = 1,2,3,4,5,6 $notenstat = 0,0,0,0,0,0,0 1..6 | ForEach{ $anzahl = 0 for($i = 0;$i -lt $noten_sa1.length; $i++) { if($noten_sa1[$i] -eq $_) { Write-Host "Note " $_ "vorhanden an Position " + ($i + 1) $anzahl++ } else { Write-Host "Note nicht vorhanden" } } $notenstat[$_] = $anzahl } Write-Host $notenstat $durchschnitt = 0 $quersumme=0 for ($i = 1; $i -lt $notenstat.length;$i++) { $quersumme += $notenstat[$i]*$i } $durchschnitt = $quersumme / $noten_sa1.length $notenstat[0] = $durchschnitt $quersumme $durchschnittEine weitere und vielleicht elegantere Möglichkeit wäre die Verwendung einer Hashmap anstelle des Arrays $notenstat. Damit müsste man die Indexpositionen nicht missbrauchen, sondern könnte die Noten als Key und die Anzahl als Values einsetzen.
Eine Lösungsansatz:
$noten_sa1 = 6,3,4,2,1,2,3,4,1,2,3,2,1,3,4,5,3,5,4,3,2,2,2,1,2,3 $notenwerte = 1,2,3,4,5,6 $notenhash = @{} 1..6 | ForEach{ $anzahl = 0 for($i = 0;$i -lt $noten_sa1.length; $i++) { if($noten_sa1[$i] -eq $_) { #Write-Host "Note " $_ "vorhanden an Position " + ($i + 1) $anzahl++ } else { # Write-Host "Note nicht vorhanden" } } $notenhash.Add($_, $anzahl) } $durchschnitt = 0 $quersumme = 0 foreach($key in $notenhash.get_Keys()) { Write-Host $key $notenhash[$key] $quersumme += $key * $notenhash[$key] } $durchschnitt = $quersumme / $noten_sa1.length $durchschnitt
Schreiben Sie eine Funktion, die als Parameter einen Pfad erwartet und anschließend den Inhalt des Pfades ausgibt
function listDirectory($pfad) { cd $pfad Dir $pfad |Out-File C:\temp\Ausgabe.txt }
Erweitern Sie die obige Funktion um eine rekursive Variante. Sollte der Pfad Unterordner besitzen, sollen auch diese ausgegeben werden.
function listDirectory($pfad) { cd $pfad Dir $pfad -recurse |Out-File C:\temp\Ausgabe.txt }
Erweitern Sie die obige Funktion: Es soll jetzt möglich sein, nach bestimmten Dateikennungen die Ausgabe zu gestalten
function listDirectory($pfad, $ext) { cd $pfad Dir $pfad -Recurse -include *.$ext |Out-File C:\temp\Ausgabe.txt }
Wie überprüfen Sie, ob ein Array einen bestimmten Wert enthält
Folgende Funktion überprüft zwei Arrays auf Gleichheit
function AreArraysEqual($a1, $a2) { if ($a1 -isnot [array] -or $a2 -isnot [array]) { throw "Both inputs must be an array" } if ($a1.Rank -ne $a2.Rank) { return $false } if ([System.Object]::ReferenceEquals($a1, $a2)) { return $true } for ($r = 0; $r -lt $a1.Rank; $r++) { if ($a1.GetLength($r) -ne $a2.GetLength($r)) { return $false } } $enum1 = $a1.GetEnumerator() $enum2 = $a2.GetEnumerator() while ($enum1.MoveNext() -and $enum2.MoveNext()) { if ($enum1.Current -ne $enum2.Current) { return $false } } return $true }
Folgendes Powershell-Skript berechnet den Wochentag mit Hilfe eines eigenen Algorythmus. Verbessern Sie die Lesbarkeit des Skriptes, indem Sie die verschiedenen Teile des Quellcode mit Hilfe von Funktionen kapseln.
<# .SYNOPSIS Fragt nach dem Teil eines Datums .DESCRIPTION Dient zum Erfassen der Bestandteile eines Datums. Macht keine Sicherheitsüberprüfungen .PARAMETER Frage Specifiziert die dem User zu stellende Frage. .OUTPUTS System.String. Gibt die von der Eingabeaufforderung übergebenen Zeichen zurück .LINK Read-Host #> function get-DatumsTeil([string]$Frage) { return Read-Host -prompt $Frage } function set-Monat() { if($m -le 2) { $m += 10; $j -= 1; } else { $m -= 2; } [int]$c = $j/100; [int]$y = $j%100; [int]$h = (((26 * $m -2)/10) + $t + $y + $y/4 + $c/4 -2 * $c)%7 if($h -lt 0) { $h +=7; } return $h } function get-Day($value) { [string]$Tag = ""; switch($h) { 0 { $Tag = "Sonntag"; break} 1 { $Tag = "Montag"; break} 2 { $Tag = "Dienstag"; break} 3 { $Tag = "Mittwoch"; break} 4 { $Tag = "Donnerstag";break} 5 { $Tag = "Freitag"; break} 6 { $Tag = "Samstag"; break} } return $Tag } $t = get-DatumsTeil("Geben Sie den Tag ein") $m = get-DatumsTeil("Geben Sie den Monat ein") $j = get-DatumsTeil("Geben Sie das Jahr ein") $MerkeMonat = $m $h = set-Monat $Tag = get-Day($h) Write-Host "Der " + $t +"." + $MerkeMonat + "." + $j + " ist ein " + $Tag
Schreiben Sie eine Funktion, die ihnen die Größe des vorhandenen physikalischen und virtuellen RAMs ausgibt. Benutzen Sie zum Ermitteln der Größe die WMI-Klasse WIN32_OperatingSystem und deren Eigenschaften FreePhysicalMemory sowie FreeVirtualMemory. Als kleine “Zugabe” möchten Sie die Angabe der Größe in verschiedenen Formaten (Byte, KByte, MByte) ermöglichen.
function get-memory ([string]$units = "b") {
$comp = get-wmiobject Win32_OperatingSystem
$mem = $comp.FreePhysicalMemory + $comp.FreeVirtualMemory
switch ($units) {
"b" {$mem}
"k" {[int]($mem / 1024)}
"m" {[int](($mem * 100) / 1048576) / 100}
}
}
siehe: http://www.gangleri.net/2009/11/25/ChangingComputerNameAndWorkgroupWithPowerShell.aspx
function Set-ComputerName
{
<#
.SYNOPSIS
Sets the name of the computer
.DESCRIPTION
Uses WMI to set the name of the computer, if the name is successfully changed the user will be prompted to reboot and apply the changes
.NOTES
File Name: ComputerName.psm1
Aurthor: Alan Bradley
Requires: PowerShell 2.0
.LINK
http://www.gangleri.net
.EXAMPLE
Set-ComputerName -Name "{New name for computer}"
.EXAMPLE
Set-ComputerName "{New name for computer}"
.EXAMPLE
Set-ComputerName -Name "{New name for computer}" -AutoReboot
.EXAMPLE
Set-ComputerName "{New name for computer}" -AutoReboot
.PARAMETER Name
The new name that the computer will be known by
#>
param(
[Parameter(Position=0, Mandatory=$true,ParameterSetName="Name")]
[string]$Name,
[Switch]$AutoReboot
)
process
{
$sysInfo = Get-WmiObject -Class Win32_ComputerSystem
$result = $sysInfo.Rename($Name)
switch($result.ReturnValue)
{
0
{
Write-Host -ForegroundColor Green "Success"
if($AutoReboot -eq $false)
{
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes",
"Reboots the machine."
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No",
"Does not reboot the machine, you will manually have to reboot this machine for changes to take effect."
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$ShouldReboot = $Host.UI.PromptForChoice("Reboot machine",
"You must reboot for change to take effect. Do you want to reboot now?", $options, 0)
}
if($ShouldReboot -eq 0 -or $AutoReboot -eq $true)
{
Restart-Computer
}
}
5 { Write-Host -ForegroundColor Red "This cmdlet must be execute with administrative privileges" }
default { Write-Host -ForegroundColor Red "Error" }
}
}
}
<#
.SYNOPSIS
Renames a computer
.DESCRIPTION
This Script will rename a computer by passing the oldComputername and the new Computername. If no names are given, a textfile will be openend
.EXAMPLE
.\Set-Computername.ps1 'oldName' 'newName'
.PARAMETER originalPCName
Old name of the computer
.PARAMETER computerName
new name of the computer
.NOTES
FileName : Download-File.ps1
Author : Steinam
LastModified : 06 Apr 2011 9:39 AM PST
#Requires -Version 2.0
#>
function Set-ComputerName {
param([switch]$help,
[string]$originalPCName=$(read-host "Please specify the current name of the computer"),
[string]$computerName=$(read-host "Please specify the new name of the computer"))
$usage = "set-ComputerName -originalPCname CurrentName -computername AnewName"
if ($help) {Write-Host $usage;break}
$computer = Get-WmiObject Win32_ComputerSystem -OriginalPCname OriginalName -computername $originalPCName
$computer.Rename($computerName)
}
#set-Computername
$computer = Get-WmiObject Win32_ComputerSystem
$computer | Format-List -Property N*
Informieren Sie sich mit Hilfe von get-help über die weiteren Möglichkeiten von Get-Eventlog
function getLogInfo([string]$Computer=".", [string]$EventLog, [string]$ErrorType)
{
}
Verändern von Attributen einer Datei
Sie haben als Administrator einige Dateien, auf die sie von Zeit zu Zeit zugreifen müssen. Um die Dateien vor versehentlichen Änderungen zu schützen, versehen Sie diese mit ReadOnly - Flag. Leider ist aber jetzt ein Bearbeiten dieser Dateien mühsam, weil Sie nun immer erst dieses Flag ändern müssen.
Schreiben Sie ein parametrisiertes Skript, welches alle Dateien eines Ordners ReadOnly bzw. Nicht-ReadOnly setzen kann. Schreiben Sie zusätzlich eine Funktion, die Ihnen alle Dateien mit ReadOnly-Flag auflistet. Eine Hilfe-Funktion soll Sie bei einer falschen Eingabe unterstützen.
http://blogs.technet.com/b/heyscriptingguy/archive/2009/09/24/hey-scripting-guy-september-24-2009.aspx
Param ([string]$path='c:\fso',
[switch]$get,
[switch]$clear,
[switch]$set,
[switch]$help
)#end param
# *** Functions here ***
Function Get-ReadOnlyFiles([string]$path)
{
"Getting readonly attribute on files in $path"
Get-ChildItem -Path $path |
Where-Object { $_.attributes -match 'readonly' }
} #end get-Readonlyfiles
Function Clear-ReadOnlyFiles([string]$path)
{
"Clearing readonly attribute from files in $path"
New-Variable -Name read_only -Value 1 -Option readonly
Get-ChildItem -Path $path |
Where-Object { $_.attributes -match 'readonly' } |
ForEach-Object {
$_.attributes = $_.attributes -Bxor $read_only }
}#end Clear-ReadonlyFiles
Function Set-ReadOnlyFiles([string]$path)
{
"Setting readonly attribute on files in $path"
New-Variable -Name read_only -Value 1 -Option readonly
Get-ChildItem -Path $path |
ForEach-Object {
$_.IsReadOnly = $True
}
}#end Set-ReadOnlyFiles
Function Get-HelpText
{
$helpText = @"
WorkWithReadOnlyFiles.ps1 -path c:\fso -get
Gets a list of all readonly files in c:\fso folder
WorkWithReadOnlyFiles.ps1 -path c:\fso -set
Sets all files in the c:\fso folder to readonly
WorkWithReadOnlyFiles.ps1 -path c:\fso -clear
Clears the readonly attribute from all files in c:\fso folder
"@
$helpText
}#end Get-HelpText
# *** Entry Point to Script ***
#$clear = $true
if($help) { Get-HelpText ; exit }
if(!$path) { "A path is required." ; Get-HelpText ; exit }
if($get) { Get-ReadOnlyFiles -path $path ; exit }
if($clear) { Clear-ReadOnlyFiles -path $path ; exit }
if($set) { Set-ReadonlyFiles -path $path ; exit }
Ein Außendienstmitarbeiter erhält ein neues Firmen-Laptop. Auf seinem alten Laptop sind viele WLAN-Profile gespeichert und Sie suchen einen Weg, um diese Profile auf den neuen Rechner ohne manuelles Neuanlegen zu übernehmen. Ein Kollege erzählt Ihnen, dass Sie mit Hilfe des Befehls netsh Profile sowie exportieren als auch importieren können.
Informieren Sie sich über die Möglichkeiten des Befehls netsh
Schreiben Sie ein Skript, welches sowohl den Export als auch den Import der WLAN-Profile ermöglicht.
function Export-WLAN { <# .SYNOPSIS Exports all-user WLAN profiles .DESCRIPTION Exports all-user WLAN profiles to Xml-files to the specified directory using netsh.exe .PARAMETER XmlDirectory Directory to export Xml configuration-files to .EXAMPLE Export-WLAN -XmlDirectory c:\temp\wlan #> [CmdletBinding()] param ( [parameter(Mandatory=$true)] [string]$XmlDirectory ) #Export all WLAN profiles to specified directory $wlans = netsh wlan show profiles | Select-String -Pattern "Profil für alle Benutzer" | Foreach-Object {$_.ToString()} $exportdata = $wlans | Foreach-Object {$_.Replace(" Profil für alle Benutzer : ",$null)} $exportdata | ForEach-Object {netsh wlan export profile $_ $XmlDirectory} } function Import-WLAN { <# .SYNOPSIS Imports all-user WLAN profiles based on Xml-files in the specified directory .DESCRIPTION Imports all-user WLAN profiles based on Xml-files in the specified directory using netsh.exe .PARAMETER XmlDirectory Directory to import Xml configuration-files from .EXAMPLE Import-WLAN -XmlDirectory c:\temp\wlan #> [CmdletBinding()] param ( [parameter(Mandatory=$true)] [string]$XmlDirectory ) #Import all WLAN Xml-files from specified directory Get-ChildItem $XmlDirectory | Where-Object {$_.extension -eq ".xml"} | ForEach-Object {netsh wlan add profile filename=($XmlDirectory+"\"+$_.name)} }
Aufruf von Remote-Desktop-Sitzungen
Erstellen Sie ein Skript, welches eine rdp-Verbindung unter Berücksichtigung verschiedener Optionen des mstsc-Befehls ermöglicht.
######################################################################################################################## # NAME # Start-RDP # # SYNOPSIS # Opens a remote desktop connection to another computer. # # SYNTAX # Start-RDP [[-Server] <string>] [[-Width] <int>] [[-Height] <int>] # Start-RDP -Path <string> [[-Width] <int>] [[-Height] <int>] # # DETAILED DESCRIPTION # The Start-RDP cmdlet opens a new Remote Desktop connection using the Microsoft Terminal Services Client. # Connection settings can be specified by argument or read from a standard RDP file. # # PARAMETERS # -Server <string> # Specifies the name of the server to connect to. May also include an IP address, domain, and/or port. # # Required? false # Position? 1 # Default value # Accept pipeline input? true # Accept wildcard characters? false # # -Width <int> # Specifies the desired width of the resolution for the connection (for non-full screen connections). # # Required? false # Position? 2 # Default value # Accept pipeline input? false # Accept wildcard characters? false # # -Height <int> # Specifies the desired height of the resolution for the connection (for non-full screen connections). # # Required? false # Position? 3 # Default value # Accept pipeline input? false # Accept wildcard characters? false # # -Path <string> # Specifies the path to an RDP file to connect with (resolution settings can be overridden using the # -Width and -Height parameters. # # Required? false # Position? 4 # Default value # Accept pipeline input? true # Accept wildcard characters? false # # -Console <SwitchParameter> # Connect to a Windows Server 2003 console session. # # Required? false # Position? named # Default value false # Accept pipeline input? false # Accept wildcard characters? false # # -Admin <SwitchParameter> # Connect to a Windows Server 2008 administrator session. # # Required? false # Position? named # Default value false # Accept pipeline input? false # Accept wildcard characters? false # # -Fullscreen <SwitchParameter> # Open connection in full screen mode. # # Required? false # Position? named # Default value false # Accept pipeline input? false # Accept wildcard characters? false # # -Public <SwitchParameter> # Run Remote Desktop in public mode. # # Required? false # Position? named # Default value false # Accept pipeline input? false # Accept wildcard characters? false # # -Span <SwitchParameter> # Span the Remote Desktop connection across multiple monitors. Each monitor must have the same height # and be arranged vertically. # # Required? false # Position? named # Default value false # Accept pipeline input? false # Accept wildcard characters? false # # INPUT TYPE # String,System.IO.FileInfo # # RETURN TYPE # # # NOTES # # -------------------------- EXAMPLE 1 -------------------------- # # C:\PS>Start-RDP # # # This command opens the Terminal Services Client connection dialog to specify a connection. # # # -------------------------- EXAMPLE 2 -------------------------- # # C:\PS>Start-RDP -Server myserver -Width 1024 -Height 768 # # # This command opens a new Remote Desktop connection to the server named "myserver" in a window with 1024x768 resolution. # # # -------------------------- EXAMPLE 3 -------------------------- # # C:\PS>Start-RDP -Server myserver -Fullscreen # # # This command opens a new full screen Remote Desktop connection to the server named "myserver". # # # -------------------------- EXAMPLE 4 -------------------------- # # C:\PS>Start-RDP -Path C:\myserver.rdp # # # This command opens a new Remote Desktop connection using the specified RDP file. # # #Function global:Start-RDP { param( [string]$Server = "", [int]$Width = "", [int]$Height = "", [string]$Path = "", [switch]$Console, [switch]$Admin, [switch]$Fullscreen, [switch]$Public, [switch]$Span ) begin { $arguments = "" $dimensions = "" $processed = $false if ($admin) { $arguments += "/admin " } elseif ($console) { $arguments += "/console " } if ($fullscreen) { $arguments += "/f " } if ($public) { $arguments += "/public " } if ($span) { $arguments += "/span " } if ($width -and $height) { $dimensions = "/w:$width /h:$height" } } process { Function script:executePath([string]$path) { Invoke-Expression "mstsc.exe '$path' $dimensions $arguments" } Function script:executeArguments([string]$Server) { Invoke-Expression "mstsc.exe /v:$server $dimensions $arguments" } if ($_) { if ($_ -is [string]) { if ($_ -imatch '\.rdp$') { if (Test-Path $_) { executePath $_ $processed = $true } else { throw "Path does not exist." } } else { executeArguments $_ $processed = $true } } elseif ($_ -is [System.IO.FileInfo]) { if (Test-Path $_.FullName) { executePath $_.FullName $processed = $true } else { throw "Path does not exist." } } elseif ($_.Path) { if (Test-Path $_.Path) { executePath $_.Path $processed = $true } else { throw "Path does not exist." } } elseif ($_.DnsName) { executeArguments $_.DnsName $processed = $true } elseif ($_.Server) { executeArguments $_.Server $processed = $true } elseif ($_.ServerName) { executeArguments $_.ServerName $processed = $true } elseif ($_.Name) { executeArguments $_.Name $processed = $true } } } end { if ($path) { if (Test-Path $path) { Invoke-Expression "mstsc.exe '$path' $dimensions $arguments" } else { throw "Path does not exist." } } elseif ($server) { Invoke-Expression "mstsc.exe /v:$server $dimensions $arguments" } elseif (-not $processed) { Invoke-Expression "mstsc.exe $dimensions $arguments" } } #}
Setzen Sie mit Hilfe der PS die IP-Adresse eines Rechners. Geben Sie auch die Daten für Gateway, SN-Mask, NIC, DNS-Server
# corrected version - $mask variable corrected to match in both places function Set-IPAddress { param( [string]$networkinterface =$(read-host "Enter the name of the NIC (ie Local Area Connection)"), [string]$ip = $(read-host "Enter an IP Address (ie 10.10.10.10)"), [string]$mask = $(read-host "Enter the subnet mask (ie 255.255.255.0)"), [string]$gateway = $(read-host "Enter the current name of the NIC you want to rename"), [string]$dns1 = $(read-host "Enter the first DNS Server (ie 10.2.0.28)"), [string]$dns2, [string]$registerDns = "TRUE" ) $dns = $dns1 if($dns2){$dns ="$dns1,$dns2"} $index = (gwmi Win32_NetworkAdapter | where {$_.netconnectionid -eq $networkinterface}).InterfaceIndex $NetInterface = Get-WmiObject Win32_NetworkAdapterConfiguration | where {$_.InterfaceIndex -eq $index} $NetInterface.EnableStatic($ip, $mask) $NetInterface.SetGateways($gateway) $NetInterface.SetDNSServerSearchOrder($dns) $NetInterface.SetDynamicDNSRegistration($registerDns) }
Mit Hilfe des Befehls net view \UNC-Name können Sie die Freigaben eines Rechners ermitteln. Schreiben Sie eine Funktion, die als Parameter einen UNC-Namen und einen speziellen Freigabetyp erwartet. Die Funktion soll dann die gefundenen Freigaben zurückgeben.
function Get-ShareNames([string]$server, [string]$ShareType)
{
<#
.SYNOPSIS
Get-Sharenames
.DESCRIPTION
Gets all printers from specified server
using intern the net view command
.Parameter Server
Specified Servername who holds the shares
.Parameter ShareType
Specify type of shares, e.g. "Drucker" or "Platte"
#>
$result = net view $server | Select-String $ShareType
#$result = net view "\\win-srv11" | Select-String "Drucker"
$ausgabe = @()
foreach($element in $result)
{
#nächste Zeile ist notwendig, da $element kein string
#sondern ein matchInfo-Objekt ist
#Wahrscheinlich wegen dem Select-String-ComandLet
$zeile = $element.toString()
$name = $zeile.split("Drucker")
$ergebnis = $name[0].TrimEnd()
$ausgabe += $ergebnis
}
return $ausgabe
}
Get-Sharenames "\\win-srv11" "Drucker"
Get-ShareNames
Virtual Memory
Get-Process | Sort-Object WorkingSet | Select-Object -First 5
Largest File
Get-ChildItem -Recurse | Where-Object { $_.Length -gt 10MB } |
Sort-Object Length -Descending | Select-Object -First 10
Foreach: Foreach-Objekt besrbeitet die Elemente der Pipeline sofort
# ForEach-Object lists each element in a pipeline:
Dir C:\ -recurse | ForEach-Object { $_.name }
Alias:
Get-Alias | where-object { $_.definition -eq "get-process" }
20 MByte-Prozesse
get-process | where-object {$_.WorkingSet64 -gt 20MB } ps | ? {$_.ws -gt 20MB }
Sortiert nach Größee
ps | ? {$_.ws -gt 20MB } | sort ws
Ausgabe Produktversion
ps | select company, name, product, productversion
Dateien
Get-Childitem h:\daten -filter *.doc -r | Where-Object { $_.Length -gt 40000 } | Select-Object Name, Length | Sort-Object Length | export-csv p:\GrosseWordDateien.csv -notype
Geben Sie alle Unterordner bis zu einer bestimmten Tiefe aus, ausgehend vom jeweils aktuellen Ordner
$Cred = New-Object System.Management.Automation.PSCredential “Administrator”, $Pw
gci -recurse | ? {$_.PSisContainer -eq $true} | where{ if(($_.fullname.split("\")).count -le 4) { write-host $_.fullname } }
Sie wollen prüfen, ob auf bestimmten Rechnern innerhalb ihres LANs Software bestimmter Hersteller vorhanden ist. Schreiben Sie ein entsprechendes Skript
########################################
# The PowerShell script inventories the installed software
# of a producer on n computer systems
# (C) Dr. Holger Schwichtenberg
########################################
$Producer = "*Microsoft*"
$EntryFilename = "computernames.txt"
$OutputFilename = "Softwareinventory.csv"
$pw = Read-Host -AsSecureString
# Import of computer names
$Computernames = Get-Content "computernames.txt"
$Computernames | foreach {
if (Ping($_))
{
Write-Host "Inventorize software for computer $_ ..."
# Fetching of installed MSI packages on all computers
$Cred = New-Object System.Management.Automation.PSCredential $_\Administrator, $Pw
$Software = foreach { get-wmiobject win32_product -computername $_ -credential $Cred }
| where { $_.vendor -like $Producer }
# Export in CSV
$Software | export-csv $OutputFileName -notypeinformation
}
else
{
Write-Error "Computer not accessible!"
}
}
# Execute Ping
function Ping
{
$status = Get-WmiObject Win32_PingStatus -�lter "Address='$args[0]'" |
select StatusCode
return $status.Statuscode -eq 0
}
Das Skript ist in mehrere Teile gegliedert:
Function Ping
# Execute Ping
function Ping
{
$status = Get-WmiObject Win32_PingStatus -�lter "Address='$args[0]'" |
select StatusCode
return $status.Statuscode -eq 0
}
Erhält als Parameter einen Computernamen, ermittelt den Statuscode und gibt true zurück, wenn der Computer erreichbar ist
Einstieg in das Skript
$Producer = "*Microsoft*" $Entry�lename = "computernames.txt" $Output�lename = "Softwareinventory.csv" # Import of computer names $Computernames = Get-Content "computernames.txt"Definition von einigen Variablen Lesen der zu überprüfenden Computernamen aus einer Textdatei
Informationsbeschaffung
$Computernames | foreach {
if (Ping($_))
{
Write-Host "Inventorize software for computer $_ ..."
# Fetching of installed MSI packages on all computers
$Software = foreach { get-wmiobject win32_product -computername $_ }
| where { $_.vendor -like $Producer }
# Export in CSV
$Software | export-csv "Softwareinventar.csv" -notypeinformation
}
else
{
Write-Error "Computer not accessible!"
}
}
Über eine Pipeline werden die Computernamen nacheinander aufgerufen Bei erfolgreichem Ping wird per WMI der Remote-Computer auf das Vorhandensein des Herstellernamens abgefragt. Bei Vorhandensein wird es als Ergebnis in eine CSV-Datei geschrieben.
Erweitern Sie obiges Skript um die Abfrage nach bestimmten Softwarenamen bzw. Versionsständen.
function Get-IsInstall($Application, $Computer, $Version)
{
$a = (Get-WmiObject -Class Win32_Product -Filter
"Name='$Application' and Version='$Version'" -computername
$Computer)
return ($a -ne $null)
}
$e = Get-IsInstall "QuickTime" "E01" "7.2.0.240"
if ($e)
{
"Software is installed!"
}
else
{
"Software is not installed!"
}
This is where PowerShell’s pipeline programming is shining. It only takes a Filter function definition, inserting it into an pre-existing pipeline and you are done.
Here is the sample script:
#Filter Function filters out records that start with "Time"
Filter Filter-Header
{
if($_ -match "^Time")
{
$_ | out-null
}
else
{
$_
}
}
cd "C:\WeatherStation\FilterTest"
#Initializing yearly file
$YearlyFileName = "Weather2009.csv"
#Set the header only once in the yearly file
Set-Content -Path $YearlyFileName -value "Time,TemperatureF,DewpointF,PressureIn,WindDirectionDegrees,WindSpeedMPH,WindSpeedGustMPH,Humidity,HourlyPrecipIn" -force -encoding "UTF8"
#Open all csv files get-content and add it to the yearly file
$Files = dir -Path "C:\Users\Klaus\Desktop\TO PLANET\WeatherStation\FilterTest" -Filter "*.csv"
#Filter in Action
$Files | ForEach-Object `
{
Get-Content -Path $_.Name -Encoding "UTF8" | Filter-Header | Add-Content -path $YearlyFileName -Encoding "UTF8"
}
Suchen Sie die letzten 2000 Systemereignisse des Eventlogs, die vom Typ “Error” sind
# PowerShell script to find Error messages in the System eventlog. Get-EventLog system -newest 2000 | where {$_.entryType -match "Error"}
Sie schreiben ein Powershell-Skript, welches eine eigene Ereignisquelle im Eventlog schafft und darunter seine Ereignisse schreibt.
## Step 1 - PowerShell Script to create eventlog source by David Stone
Clear-Host
if (!(test-path ` HKLM:\SYSTEM\CurrentControlSet\Services\Eventlog\Application\SampleApp )) `
{new-eventlog -logname Application -source SampleApp `
-ErrorAction SilentlyContinue}
## Step 2 - Create a 'Job start' entry in your event log
$startTime = Get-date
$startLog = 'Sample job started at ' +$startTime+ ' local time'
write-eventlog -LogName Application -Message $startLog -Source SampleApp `
-id 1 -entrytype Information -Category 0
## Step 3 - A production script would have a payload here.
## Step 4 - Write errors during processing (typically part of a if statement)
write-eventLog -LogName Application -Message 'Message content' `
-Source SampleApp -id 100 -entrytype Warning -category 0
## Step 5 - Write end of process entry in your event log
$endTime = Get-date
$endLog = 'Sample job ended at ' +$endTime+ ' local time'
write-eventlog -LogName Application -Message $endLog -Source SampleApp `
-id 9 -entrytype Information -category 0
Schreiben Sie die Einträge der obigen Quelle in eine CSV-Datei. Es soll nur die jeweils letzte Stunde eingetragen werden
## Step 6 - Write the entries to a csv file Clear-Host $logtime=[DateTime]::Now.AddHours(-1) $CSVPath = "C:\SSource.csv" Get-EventLog -LogName application -Source 'SampleApp' ` -EntryType warning -After $logtime ` | select eventid, machinename, entrytype, source, message, timegenerated ` | Export-Csv $CSVPath -NoTypeInformation
A Real-life Example of Select-String
My practical problem was that I wanted to search for instances a particular string in a directory with hundreds of file. If a file had duplicate entries, then I needed to know.
The PowerShell problem is how to create a stream of the files, then compare each file with my string value. In the output I needed to know the filename.
To solve the problem, I employed four main commands, which you can see in the following script:
Get-ChildItem - recurse
foreach (loop) {what to do block}
if (test) {output block}
select-String -pattern to match my string value.
# A real-life example of PowerShell's Select-String
$i=0
$File = Get-ChildItem "C:\html" -include *.html -recurse
$StringVid = "msbuild"
foreach ($Entry in $File) {
$List = select-string -pattern $StringVid $Entry
if ($List.LongLength -gt 1) {
"{0,-8} {1,-4} {2,18}" -f
"Files ", $List.LongLength, $Entry.FullName;
$i++
}
}
Namensauflösung einer IP-Range
Die Programmfunktionalität wird mit Hilfe von 2 Funktionen realisiert. Get-ComputerNameByIP zeigt die Verwendung von Fehlerbehandlungscode, Check-Online zeigt die Verwendung von Hintergrundprozessen.
Als Speicher für die IP-Adressen und Hostnamen wird die Datenstruktur eines Hashes verwendet,
<#
.SYNOPSIS
Gets a computer name
.DESCRIPTION
Resolve a computer name using an IP address
.PARAMETER <paramName>
$IPAddress
.EXAMPLE
Get-ComputerNameByIP "192.168.1.1"
.AUTHOR
G.W. Scheppink
#>
function Get-ComputerNameByIP {
param(
$IPAddress = $null
)
begin { }
process {
if ($IPAddress -and $_) {
Throw "Please use either pipeline or input parameter"
break
} elseif ($IPAddress) {
([System.Net.Dns]::GetHostbyAddress($IPAddress))
} elseif ($_) {
trap [Exception] {
write-warning $_.Exception.Message
continue;
}
[System.Net.Dns]::GetHostbyAddress($_)
} else {
$IPAddress = Read-Host "Please supply the IP Address"
[System.Net.Dns]::GetHostbyAddress($IPAddress)
}
}
end { }
} # End function
function Check-Online {
param(
$computername
)
test-connection -count 1 -ComputerName $computername -TimeToLive 5 -asJob |
Wait-Job |
Receive-Job |
Where-Object { $_.StatusCode -eq 0 } |
Select-Object -ExpandProperty Address StatusCode
}
# This code pings an IP segment from 192.168.1.1 to 192.168.1.254 and returns only those IPs that respond.
CLS
$ip_name = @{}
$Start = Get-Date
$ips = 1..254 | ForEach-Object { "192.168.0.$_" }
$online = Check-Online -computername $ips
$online
foreach ($PC in $online) {
$pcname = Get-ComputerNameByIP $PC
$ip_name+=@{$PC=$pcname.HostName}
}
$End = Get-Date
Write-Host "`nStarted at: " $Start
Write-Host "Ended at: " $End
$ip_name
#umständliches Schreiben der key-value-Paare aus einem Hash heraus
$ip_name.GetEnumerator() | Sort-Object Name |
ForEach-Object {"{0} , {1}" -f $_.Name,$_.Value} |
Add-Content C:\temp\log.csv`
Laptop oder Desktop
Sie sind die IT-Leiter einer kleinen mittelständischen Firma. Sie müssen Inventur machen und Sie brauchen dazu die Anzahl der zur Zeit sich im Netz befindlichen Laptop-und Desktop-Computer in ihrer Firma.
Following is the full script. <# .Synopsis helper function used by Get-HardwareType .EXAMPLE Example of how to use this cmdlet #> function Is-Laptop { [CmdletBinding()] [OutputType([boolean])] param ( [Parameter(Mandatory=$true)] [string] $strHostName ) $blnResult = $false $query = "select __SERVER,ChassisTypes from Win32_SystemEnclosure" $objWMI = Get-WmiObject -ComputerName $strHostName -Query $query -ErrorAction Stop switch ($objWMI.ChassisTypes) { 9 {$blnResult = $true} # Laptop 10 {$blnResult = $true} # Notebook 12 {$blnResult = $true} # Docking Station 14 {$blnResult = $true} # Sub Notebook default {} } return $blnResult } # end function <# .Synopsis function to determine chassis type using a WMI query .DESCRIPTION function to determine chassis type using a WMI query .EXAMPLE "pc01","pc02","pc03" | Get-HardwareType #> function Get-HardwareType { [CmdletBinding()] [OutputType([psobject])] Param ( [Parameter(Mandatory=$true,ValueFromPipeline=$true)] $strHostName ) process { try { $objHostName = [system.net.dns]::GetHostByName($strHostName) $query = "select __SERVER,ChassisTypes from Win32_SystemEnclosure" if (Test-Connection -ComputerName $objHostName.HostName -count 1 -erroraction silentlycontinue) { try { $objResult = New-Object -TypeName psobject -Property @{HostName=$objHostName.HostName;IsLaptop=(Is-Laptop -strHostName $objHostName.HostName)} return $objResult } catch { "Error trying to query $($objHostName.HostName)" } } else { write-host "error connecting to $($objHostName.HostName)" } } catch { write-host "Unable to resolve DNS address for $strHostName" } } } # end function $laptopCount = 0 $desktopCount = 0 $searcher = new-object directoryservices.directorysearcher([ADSI]"","(&(objectcategory=computer)(!operatingsystem=*server*))") [void]$searcher.PropertiesToLoad.Add("cn") $arrMachineName = $searcher.findall() | %{$_.properties.cn} $result = $arrMachineName | Get-HardwareType $result $result | ForEach-Object {if ($_.islaptop) {$laptopCount++} else {$desktopCount++}} "Laptop Total: $laptopCount" "Desktop Total: $desktopCount" ## beim Lesen aus Textdatei #$result = import-csv C:\temp\laptop_desktop.ps1 | Group-Object {$_.chassis} -noelement #$result = import-csv C:\temp\laptop_desktop.ps1 | Group-Object -property chassis -noelement #$result
$strComputer = "."
# Neues leeres Objekt erstellen
$Infos= New-object -TypeName PSObject
# Wert an das Objekt anfügen
Add-Member -InputObject $Infos -Name Manufacturer -Value 1 -MemberType NoteProperty
# Wert an das Objekt anfügen
Add-Member -InputObject $Infos -Name Model -Value 2 -MemberType NoteProperty
# Wert an das Objekt anfügen
Add-Member -InputObject $Infos -Name Memory -Value 3 -MemberType NoteProperty
Add-Member -InputObject $Infos -Name BiosDescription -Value 3 -MemberType NoteProperty
Add-Member -InputObject $Infos -Name SerialNumber -Value 3 -MemberType NoteProperty
Add-Member -InputObject $Infos -Name OperatingSystem -Value 3 -MemberType NoteProperty
Function SysInfo($Infos)
{
$colItems = Get-WmiObject Win32_ComputerSystem `
-Namespace "root\CIMV2" -ComputerName $strComputer
foreach($objItem in $colItems) {
$Infos.Manufacturer = $objItem.Manufacturer
$Infos.Model = $objItem.Model
$Infos.Memory = $objItem.TotalPhysicalMemory
}
}
Function BIOSInfo($Infos)
{
$colItems = Get-WmiObject Win32_BIOS -Namespace "root\CIMV2" `
-computername $strComputer
foreach($objItem in $colItems) {
$Infos.BiosDescription = $objItem.Description
$Infos.SerialNumber = $objItem.SerialNumber
}
}
Function OSInfo($Infos)
{
$colItems = Get-WmiObject Win32_OperatingSystem -Namespace ` "root\CIMV2" -Computername $strComputer
foreach($objItem in $colItems) {
$Infos.OperatingSystem = $objItem.Name
}
}
#*=============================================================
#* SCRIPT BODY
#*=============================================================
#* Connect to computer
#* Call SysInfo Function
Write-Host "Sytem Information"
SysInfo $Infos
#* Call BIOSinfo Function
Write-Host "System BIOS Information"
BIOSInfo $Infos
Write-Host
#* Call OSInfo Function
Write-Host "Operating System Information"
OSInfo $Infos
Write-Host
$Infos | Select-Object Name, Model
# CSV Export der Daten
Export-Csv -InputObject $Infos -Path "C:\Temp\infos.csv"
`
Measure-Command{
$site_urls = Import-CSV C:\temp\weekly_stats.csv
function bla
{
foreach($url in $site_urls)
{
$obj_avg = New-Object -TypeName psobject
Add-Member -InputObject $obj_avg -MemberType NoteProperty -Name "site_url" -Value $url.site_url
Add-Member -InputObject $obj_avg -MemberType NoteProperty -Name "url_avg" `
-Value ([int](([int]$url.monday + [int]$url.tuesday + [int]$url.wednesday + [int]$url.thursday + [int]$url.friday + [int]$url.saturday + [int]$url.sunday)/7))
$obj_avg
}
}
bla | Sort-Object url_avg
}
Measure-Command {
$site_urls2 = Import-CSV C:\temp\weekly_stats.csv
$site_urls2 | Select @{name="site_url";expression={$_.site_url}}, `
@{name="avg";expression={([int](([int]$_.monday + [int]$_.tuesday + [int]$_.wednesday + [int]$_.thursday + [int]$_.friday + [int]$_.saturday + [int]$_.sunday)/7))}} | `
Sort-Object avg
}
add-type @"
using System;
public class siteurl{
public string url = "";
public double durchschnitt = 0;
public void seturl(string _url)
{
this.url = _url;
}
public void avg(int mon, int tue, int wed, int thu, int fri, int sat, int sun)
{
this.durchschnitt = ((monday+tuesday+wednesday+ thursday + friday+ saturday + sunday)/7);
}
}
"@
Measure-Command {
function bla2
{
$site_urls = Import-CSV C:\temp\weekly_stats.csv
foreach($url in $site_urls)
{
$net_avg = New-Object -typename siteurl
$net_avg.seturl($url.site_url)
$net_avg.avg($url.monday,$url.tuesday,$url.wednesday,$url.thursday,$url.friday,$url.saturday,$url.sunday)
$net_avg
}
}
bla2 |select url, durchschnitt | Sort-Object durchschnitt
`
Gegeben ist folgendes PS-Skript.
Function Get-NetworkConfiguration
{
param (
[parameter(
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[Alias('__ServerName', 'Server', 'Computer', 'Name')]
[string[]]
$ComputerName = $env:COMPUTERNAME,
[parameter(Position=1)]
[System.Management.Automation.PSCredential]
$Credential
)
process
{
$WMIParameters = @{
Wählen Sie statt der Write-Host-Ausgabe einen objektorientieten Ansatz
Der foreach-teil muss wie folgt geändert werden:
foreach ($adapter in (Get-WmiObject @WMIParameters))
{
$AdapterProperties = @{
Server = $adapter.DNSHostName
Adapter = $adapter.Description
IPAddress = $adapter.IpAddress
SubnetMask = $adapter.IPSubnet
DefaultGateway = $adapter.DefaultIPGateway
DNSServers = $adapter.DNSServerSearchOrder
DNSDomain = $adapter.DNSDomain
}
New-Object PSObject -Property $AdapterProperties
}
Sie wollen nicht alle Informationen ausgeben, sondern beispielsweise nur die IP-Adresse und die Subnet-Maske
Get-NetworkConfiguration ‘Server1’, ‘Server2’, ‘Server3’ | Format-Table Server, Adapter, SubnetMask, DefaultGateway –auto –wrap
Können Sie mit diesem Skript mehrere Rechner abfragen ?
ja
Welche Rechner ihres Netzes benutzen den gleichen DNS-Server mit der IP-Adresse *.*.***.***. Eine Liste der Computer erhalten Sie mit Hilfe des CommandLets get-adcomputer
Get-ADComputer –filter * | Get-NetworkConfiguration | Where-Object {$_.DNSServers –contains $IPofMyTroublesomeDNSServer}
Wie viele Rechner benutzen den gleichen Default-Gateway
Get-ADComputer -filter * | Get-NetworkConfiguration | Group-Object DefaultGateway -NoElement