Was machen diese Powershellbefehle?
Ich habe follgendes Script mit folgenden Kommentaren:
# Nach dem Quellordner fragen
$sourceFolder = Read-Host "Quellordner"
# Nach dem Zielordner fragen
$targetFolder = Read-Host "Zielordner"
$SearchFile = 'ManualToHelpCmd.exe' # Datei welche gesucht werden soll
$ExcludeFolders = 'Windows','Video' # Hauptordner in Laufwerken, welche überhaupt nicht durchsucht werden sollen
# ermittle alle lokalen Laufwerke (HDD, SSD, USB, SD...) (keine CD, DVD)
$Drives = (Get-CimInstance -ClassName Win32_LogicalDisk -Filter 'DriveType = 3 or DriveType = 2').DeviceID -as [Array]
# Get-CimInstance:Instanzen einer bestimmten Klasse aus dem CIM (Common Information Model) abruft
# ClassName Win32_LogicalDisk: Gibt an, dass Informationen aus der Klasse Win32_LogicalDisk abgerufen werden sollen die Laufwerke auf dem System beschreibt
# Filter 'DriveType = 3 or DriveType = 2': Ein Filter der nur die logischen Laufwerke auswählt deren DriveType gleich 3 oder 2 ist. DriveType 3 steht für lokale Festplatten, und DriveType 2 steht für Wechseldatenträger (z.B. USB-Sticks).
# DeviceID: Greift auf die DeviceID-Eigenschaft der zurückgegebenen logischen Laufwerke zu, was die Laufwerksbuchstaben (z.B. C:, D:) darstellt
# -as [Array]: Konvertiert die Liste der DeviceIDs in ein Array
# Überprüfen, ob Laufwerke gefunden wurden
if (-not $Drives) {
Write-Host "Keine Laufwerke gefunden." -ForegroundColor Red
exit
}
# das eigentliche Arbeitspferd
$Worker = {
param(
[Array]$Drives,
[String]$Filter,
[Array]$ExcludeFolders
)
# param(: Definiere die Parameter die der Skriptblock akzeptiert
# [Array]$Drives: Ein Array von Laufwerken
# [String]$Filter: Ein String-Filter
# [Array]$ExcludeFolders: Ein Array von auszuschließenden Ordnern
$Results = @() #Initialisiert eine leere Array-Variable namens "Results" die verwendet wird um die Ergebnisse zu speichern.
foreach ($Drive in $Drives) { #Jedes Element wird in der Variablen $Drive gespeichert.
$Results += (Get-ChildItem "$Drive\" -File -Filter $Filter -ErrorAction SilentlyContinue).FullName #-ErrorAction: Dieser Parameter steuert, wie das Cmdlet auf Fehler reagiert. SilentlyContinue: Diese Einstellung bewirkt, dass Fehler zwar erkannt, aber nicht angezeigt werden. Filtert hier sozusagen anch den Fehlern aber gibt sie nicht aus
$Results += (Get-ChildItem "$Drive\" -Directory | Where-Object Name -notin $ExcludeFolders | Get-ChildItem -File -Filter $Filter -Recurse -ErrorAction SilentlyContinue).FullName #-Directory = nur buchstaben, | = und, Recurse = sucht in
}
return $Results
}
# die Suche starten...
if ($Drives.Length -lt 2) {
# wenn wir nur ein (Physikalisches) Laufwerk haben können wir die Verteilung auf mehrere Jobs sparen, einfach den Worker direkt ausführen
Write-Host "$($Drives.Length) physikalische Festplatte(n), Suche wird einstufig durchgeführt:" -ForegroundColor Magenta
$Result = & $Worker -Drives $Drives -Filter $SearchFile -ExcludeFolders $ExcludeFolders
} else {
# bei mehreren Laufwerken die Arbeit auf mehrere parallele Jobs verteilen
$Jobs = $Drives | ForEach-Object {
Write-Host "Festplatte $_ wird durchsucht" -ForegroundColor Green
Start-Job -ScriptBlock $Worker -ArgumentList @($_ , $SearchFile, $ExcludeFolders)
}
$Result = $Jobs | Wait-Job | Receive-Job | Where-Object {$_}
}
# Debugging-Ausgabe für die gefundenen Ergebnisse
Write-Host "Gefundene Dateien:" -ForegroundColor Cyan
$Result | ForEach-Object { Write-Host $_ -ForegroundColor Cyan }
if ($Result) {
# Wenn mehrere Dateien gefunden werden, Auswahl anzeigen
if ($Result.Count -gt 1) {
Write-Host "Es wurden mehrere Dateien gefunden mit gleichnamigen Namen. Wählen Sie die gewünschte Datei aus!" -ForegroundColor Yellow
$selectedFile = $Result | Out-GridView -Title "Wählen Sie die Datei aus, welche Sie benutzen wollen!" -OutputMode Single
} else {
$selectedFile = $Result
}
# Das Ergebnis (können auch mehrere Dateien gleichen Namens sein)
if ($selectedFile) {
Write-Host "Ausgewählte Datei: $selectedFile" -ForegroundColor Green
& $selectedFile $sourceFolder $targetFolder
} else {
Write-Host "Keine Datei ausgewählt" -ForegroundColor Red
}
} else {
Write-Host "Keine Datei gefunden" -ForegroundColor Red
}
Aber was machen diese zwei Zeilen?:
$Results += (Get-ChildItem "$Drive\" -File -Filter $Filter -ErrorAction SilentlyContinue).FullName
$Results += (Get-ChildItem "$Drive\" -Directory | Where-Object Name -notin $ExcludeFolders | Get-ChildItem -File -Filter $Filter -Recurse -ErrorAction SilentlyContinue).FullName
2 Antworten
$Results += (Get-ChildItem "$Drive\" -File -Filter $Filter -ErrorAction SilentlyContinue).FullName
....durchsucht das Wurzelverzeichnis des in der Variable $Drive übergebenen Laufwerks. (bei C: ist das "C:\ ") -nur nach Dateien mit der Filtermaske ManualToHelpCmd.exe . .FullName beschränkt den Rückgabewert auf die Property "FullName" . Das eventuelle Ergebnis wird der Arrayvariable $Result hinzugefügt (oder auch Nichts)
Lange Pipelines sind immer schwer zu lesen und kommentieren, darum schreibe ich sie mal über mehrere Zeilen...
$Results += (
Get-ChildItem "c:\" -Directory | #ermittelt nur die Ordner im Rootverzeichnis des Laufwerks
Where-Object Name -notin @('windows','video') | # entferne eventuell gefundene Ordner mit mit den Namen 'Windows' und 'Video' aus der Pipeline
Get-ChildItem -File -Filter 'ManualToHelpCmd.exe' -Recurse -ErrorAction SilentlyContinue #durchsuche die in der Pipeline verbliebenen Ordner rekursiv nach dateien mit der Filtermaske 'ManualToHelpCmd.exe'
).FullName
...und ebenfalls zu $Results hinzufügen
das kann man auch in der Powershell dokumentation nachlesen
- https://learn.microsoft.com/de-de/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-5.1
- https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-5.1
- https://learn.microsoft.com/de-de/powershell/module/microsoft.powershell.core/about/about_pipelines?view=powershell-5.1
wenn Du mal wieder nicht genau weißt was Befehl/pipelines alles zurückgeben führe sie einzeln aus :
auch Begriffe wie .FullName schüttle ich mir nicht aus den Ärmeln.
wenn due wissen möchtest, welche Eigenschaften ein beliebiges Dateiobjekt verfügt.
genügt :
gci -file| #dateien im aktuellen verzeichnis
select -first 1| #das erste beste
Format-List * #alle ermittelten Eigenschaften auflisten
und sowas wird ausgegeben:
Einfach erklärt durchsuchen diese zwei Zeilen alle angegebenen Laufwerke nach einer bestimmten Datei. Die erste Zeile sucht nur im Root-Verzeichnis der Laufwerke, während die zweite Zeile rekursiv alle Unterverzeichnisse durchsucht, außer den ausgeschlossenen Ordnern. Die Ergebnisse werden in der $Results-Variablen gesammelt.