Gibt es eine Möglichkeit, interaktive Eingabeaufforderungen in einem PowerShell-Skript zu unterdrücken?


13

Beim Schreiben von PowerShell-Skripten habe ich festgestellt, dass bei bestimmten Cmdlets Probleme auftreten. Dabei wird eine interaktive Eingabeaufforderung angezeigt. Als Beispiel wird "Remove-Item" in einem nicht leeren Verzeichnis angezeigt. Dies ist tödlich, wenn Sie versuchen, Aufgaben zu automatisieren. Ich würde es vorziehen, wenn die Aktion einfach fehlschlägt und entweder eine Ausnahme auslöst oder einen fehlerhaften Rückkehrcode zurückgibt, damit das gesamte Skript nicht auf eine Antwort wartet.

Gibt es eine Möglichkeit, PowerShell zum automatischen Fehlschlagen zu zwingen, anstatt Benutzereingaben für Aktionen zu suchen?


Ich denke, Sie sollten Ihre Frage "Wie kann ich Remove-Itemschnell scheitern lassen?" Umbenennen.
Jay Bazuzi

1
Hier geht es nicht speziell um Remove-Item, sondern nur um ein anschauliches Beispiel. Es gibt viele andere Cmdlets, die das Warten auf Benutzereingaben unter den richtigen Bedingungen blockieren.
Chuu

Antworten:


5

Die von Eris vorgeschlagene Lösung startet effektiv eine andere PowerShell-Instanz. Eine alternative Möglichkeit, dies mit einfacherer Syntax zu tun, besteht darin, auf eine andere Instanz von Powershell.exe zuzugreifen.

powershell.exe -NonInteractive -Command "Remove-Item 'D:\Temp\t'"

2
Ich mag die Lösung wirklich, aber sie bringt Albträume zurück, zuverlässige gespeicherte Prozeduren in TSQL vor TRY / CATCH zu schreiben, was es erforderlich machte, buchstäblich jede Abfrage mit Fehlererkennungs-Boilerplate zu umgeben.
Chuu

4

Siehe Get-Help about_Preference_Variables:

$ ConfirmPreference
------------------ ------------------.
    Legt fest, ob Windows PowerShell Sie automatisch dazu auffordert
    Bestätigung vor dem Ausführen eines Cmdlets oder einer Funktion.

...

Keine: Windows PowerShell fordert nicht automatisch dazu auf.
                         Verwenden Sie, um die Bestätigung eines bestimmten Befehls anzufordern
                         Der Confirm-Parameter des Cmdlets oder der Funktion.

So:

> $ConfirmPreference = 'None'

Ich fand das, um das Problem zu sehen, das ich einstellen musste. $ ConfirmPreference = 'Niedrig'
Guy Thomas

Dies scheint nicht zu funktionieren. Remove-Item in einem Verzeichnis gibt Ihnen weiterhin eine Eingabeaufforderung, nachdem Sie $ ConfirmPreference auf 'None' oder 'Low' gesetzt haben
Chuu

Funktioniert für Remove-ADUser(Server 2012R)
Velkoon

2

Ok, das ist wirklich hässlich, aber heilige Senfflecken es "funktioniert".

Probleme:

  • Ich habe nicht herausgefunden, wie ich nach dem ersten Fehler fortfahren soll
  • In diesem Fall werden einfache Dateien entfernt und beim ersten Ordner angehalten
  • Ich habe nicht herausgefunden, wie dieses Cmdlet funktioniert, wenn ich den UseTransaction-Parameter hinzufüge
  • Dies funktioniert nur für den einfachen Fall (Befehle, die mit der aktuellen Umgebung nicht viel zu tun haben). Ich habe nichts Komplexes getestet

    $MyPS = [Powershell]::Create()
    $MyPS.Commands.AddCommand("Remove-Item")
    $MyPS.Commands.AddParameter("Path", "D:\Temp\t")
    $MyPS.Invoke()

Ausgabe:

Commands                                                                                                                 
--------                                                                                                                 
{Remove-Item}                                                                                                            
{Remove-Item}                                                                                                            
Exception calling "Invoke" with "0" argument(s): "A command that prompts the user failed because the host program or the 
command type does not support user interaction. The host was attempting to request confirmation with the following 
message: The item at D:\Temp\t has children and the Recurse parameter was not specified. If you continue, all children 
will be removed with the item. Are you sure you want to continue?"
At line:19 char:1
+ $MyPS.Invoke()
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : CmdletInvocationException

Der Grund, warum ich dies nicht als Lösung markiert habe, ist, dass ich keine Zeit gefunden habe, es zu testen. Hat jemand außer dem Autor diesen Code bereitgestellt oder getestet?
Chuu

0

Alle oben genannten Lösungen sind für mich fehlgeschlagen, als ich ein Verzeichnis erstellt habe. Dies bedeutete, dass ich aufgefordert wurde, jedes einzelne Verzeichnis, das mein Skript erstellt hat, zu bestätigen - was sehr viel war. Was für mich funktioniert hat, war apped | Out-null, um die Ergebnisse an Out-Null weiterzuleiten

New-Item -ItemType Directory -Path $directory -Force:$true | Out-Null

Beachten Sie, dass $ Directory eine Zeichenfolge mit dem vollständigen Pfad zu dem Verzeichnis ist, das Sie erstellen möchten. Hoffe das spart jemandem etwas Zeit: P.


-1

Ich schlage zwei Techniken vor

a) Anhängen -force

b) Anhängen -errorAction silently continue

So recherchiere ich, welche Cmdlets einen bestimmten Parameter unterstützen

Get-Command | where { $_.parameters.keys -contains "erroraction"}

Einer der Gründe, warum ich diesen Weg eingeschlagen habe, ist, dass ich normalerweise das Gegenteil von -force tun möchte, dh so etwas wie -alwaysbackoff. Ich habe festgestellt, dass die meisten Befehle, die -force unterstützen, keine Option zum Zurücksetzen zu haben scheinen.
Chuu

1
Als beiseite, für eine bequeme Abkürzung -errorAction SilentlyContinueist -ea 0.
Jay Bazuzi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.