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
Das is schon klar dass die daten benötigt werden und war ja auch nicht die frage, es geht mir um die technische Lösung dessen - es gibt ja auch plugins und es kann ja sein, dass da jemand was programmiert hat - das Problem werden bestimmt noch mehr haben.