WinFuture-Forum.de: Windows Powershell ParameterBindingValidationException - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
Seite 1 von 1

Windows Powershell ParameterBindingValidationException


#1 Mitglied ist offline   Feldhase 

  • Gruppe: aktive Mitglieder
  • Beiträge: 28
  • Beigetreten: 10. Dezember 12
  • Reputation: 0

geschrieben 19. Januar 2015 - 14:51

Ich habe zwar keine Ahnung in Powershell, muss aber trotzdem nen kleines Script zum löschen von Dateien schreiben. Das Script löscht zwar die Dateien, aber wirft mir auch ne Fehlermeldung raus. Kann mir jemand weiter helfen warum ich den Fehler bekomme bzw. wie ich ihn vermeide?

Fehler:
Remove-Item : Das Argument kann nicht an den Parameter "Path" gebunden werden, da es NULL ist.
Bei Zeile:7 Zeichen:20
+ Remove-Item <<<< $dat.FullName -whatif
+ CategoryInfo : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveItemCommand

Script:
$Startordner="F:\";
$ordner = Get-ChildItem -Path $Startordner -recurse | Where-Object {$_.FullName -like "*protokolle" -and $_.PSIsContainer -eq $True}

foreach ($ord in $ordner) {
$datei = Get-ChildItem -Path $ord.fullname | Where-Object {$_.PSIsContainer -eq $False -and $_.lastwritetime -lt (Get-Date).AddMonths(-12)}

foreach ($dat in $datei) {
Remove-Item $dat.FullName -whatif
}
}
0

Anzeige



#2 Mitglied ist offline   DK2000 

  • Gruppe: Administration
  • Beiträge: 19.809
  • Beigetreten: 19. August 04
  • Reputation: 1.435
  • Geschlecht:Männlich
  • Wohnort:Oben auf dem Berg
  • Interessen:Essen, PC, Filme, TV Serien...

geschrieben 19. Januar 2015 - 15:48

Irgendwas liefert da keinen Rückgabewert. Jedenfalls ist $dat.FullName am Ende leer und deswegen kommt es zum Fehler ErrorNullNotAllowed.

Wenn Du das so machst, müsste die Zeile so aussehen:

$ordner = Get-ChildItem -Path $Startordner -recurse | Where{ $_.name -like "*protokolle" }|Select-Object FullName

Das liefert jetzt nur die Ordnernamen mit vollem Pfad zurück. Wobei ich mir gerade nicht sicher bin, ob das wirklich das ist, was Du Dir vorstellst. Was ist "*protokolle"? Ordner oder Dateien? Er liefert jetzt nur Ordner zurück, welche "protokolle" im Namen enthalten, aber keine Ordner, welche Dateien mit dem Namen "*protokolle" enthalten.

foreach ($ord in $ordner) {
   $datei = Get-ChildItem $ord | where-object {!$_.PSIsContainer -and $_.lastwritetime -gt (get-date).AddMonths(-12)} | foreach { $_.FullName }
   Remove-Item $datei -whatif
}

So sollte es funktionieren. Wobei es unsauber ist. Würde nur funktionieren, wenn immer etwas zu löschen gefunden wird. Sollte man eventuell noch eine if einbauen:

if ($datei -ne $null){ Remove-Item $datei -whatif }

Jetzt würde er nur noch Remove-Item ausführen, wenn die Variable einen Wert enthält. Ist die Variable leer, wird das übersprungen.
Ich bin kein Toilettenpapier-Hamster.
---
Ich bin ein kleiner, schnickeldischnuckeliger Tiger aus dem Schwarzwald.
Alle haben mich ganz dolle lila lieb.
0

#3 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.902
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 19. Januar 2015 - 19:00

Ohne jetzt weiter die Scriptlogik angeschaut zu haben: in der for()-Schleife am Ende wird $datei immer wieder üb erschrieben. Wenn das letzte betrachtete Element halt nicht in den where-Filter paßt, wird $datei dann halt NULL.

Unter PS muß man nur vergleichsweise selten mit Schleifen arbeiten. Das arbeitet mit Objekten und Listen von Objekten gleichermaßen. Du kannst also Get-ChildItem -Recurse... mit einem Filter belegen und das Ergebnis in ein Objekt stecken. Dann mit echo $objekt | ... weiterbearbeiten (das 'echo' funktioniert auch implizit = man kann es weglassen).

Sinngemäß sollte sowas wie
Get-ChildItem -Recurse ... | Where-Object {...} | Remove-Item


bereits funktionieren. Dann muß in den Where-Object Codeblock alles das rein, was für die Filterung notwendig ist - wichtig, am Ende muß der Codeblock was zurückgeben, also ggf. $ergebnis oder echo $ergebnis ans Ende schreiben, wenn das Ergebnisobjekt in $ergebnis gesteckt hatte.
"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

#4 Mitglied ist offline   Feldhase 

  • Gruppe: aktive Mitglieder
  • Beiträge: 28
  • Beigetreten: 10. Dezember 12
  • Reputation: 0

geschrieben 20. Januar 2015 - 07:51

 Zitat (DK2000: 19. Januar 2015 - 15:48)

Das liefert jetzt nur die Ordnernamen mit vollem Pfad zurück. Wobei ich mir gerade nicht sicher bin, ob das wirklich das ist, was Du Dir vorstellst. Was ist "*protokolle"? Ordner oder Dateien? Er liefert jetzt nur Ordner zurück, welche "protokolle" im Namen enthalten, aber keine Ordner, welche Dateien mit dem Namen "*protokolle" enthalten.

Ist schon richtig so, ich suche nur nach Ordner mit dem Namen protokolle.

 Zitat (RalphS: 19. Januar 2015 - 19:00)

Unter PS muß man nur vergleichsweise selten mit Schleifen arbeiten. Das arbeitet mit Objekten und Listen von Objekten gleichermaßen. Du kannst also Get-ChildItem -Recurse... mit einem Filter belegen und das Ergebnis in ein Objekt stecken. Dann mit echo $objekt | ... weiterbearbeiten (das 'echo' funktioniert auch implizit = man kann es weglassen).

Sinngemäß sollte sowas wie
Get-ChildItem -Recurse ... | Where-Object {...} | Remove-Item


Mit den Schleifen bin ich wohl zu stark an C# und Java gewöhnt. So hat es jetzt aber geklappt:
 (Get-ChildItem .....) | Where-Object {....} | % {Remove-Item $_.FullName -whatif} 


Danke für die Hilfe.
0

Thema verteilen:


Seite 1 von 1

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0