Esiste un modo per sopprimere eventuali prompt interattivi in ​​uno script di PowerShell?


13

Durante la scrittura di script PowerShell, ho notato che quando alcuni cmdlet incontrano problemi generano un prompt interattivo, ad esempio Remove-Item su una directory non vuota. Questo è mortale quando si tenta di automatizzare le attività, preferirei che l'azione fallisse e che generasse un'eccezione o restituisse un codice di ritorno errato in modo che l'intero script non fosse bloccato in attesa di una risposta.

Esiste un modo per forzare il fallimento automatico di PowerShell anziché cercare l'input dell'utente sulle azioni?


Penso che dovresti rinominare la tua domanda "Come posso far Remove-Itemfallire velocemente?"
Jay Bazuzi,

1
Questo non riguarda specificamente Rimuovi-Articolo, è solo un esempio illustrativo. Esistono molti altri cmdlet che bloccano l'attesa dell'input dell'utente nelle giuste condizioni.
Chuu,

Risposte:


5

La soluzione proposta da Eris avvia effettivamente un'altra istanza di PowerShell. Un modo alternativo per eseguire questa operazione, con una sintassi più semplice, è eseguire il shell out su un'altra istanza di powershell.exe.

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

2
Mi piace molto la soluzione, ma riporta gli incubi della scrittura di procedure memorizzate affidabili in TSQL prima di TRY / CATCH che richiedevano letteralmente di circondare ogni query con la piastra di rilevamento degli errori.
Chuu,

4

Vedi Get-Help about_Preference_Variables:

$ ConfirmPreference
------------------
    Determina se Windows PowerShell richiede automaticamente
    conferma prima di eseguire un cmdlet o una funzione.

...

Nessuna: Windows PowerShell non richiede automaticamente.
                         Per richiedere la conferma di un determinato comando, utilizzare
                         il parametro di conferma del cmdlet o della funzione.

Così:

> $ConfirmPreference = 'None'

Ho scoperto che per vedere il problema ho dovuto risolvere. $ ConfirmPreference = 'Low'
Guy Thomas

Questo non sembra funzionare. Rimuovi-Item su una directory ti dà ancora un prompt dopo aver impostato $ ConfirmPreference su 'None' o 'Low'
Chuu

Funziona per Remove-ADUser(Server 2012R)
Velkoon,

2

Ok, questo è davvero brutto, ma la senape santa macchia "funziona".

Problemi:

  • Non ho capito come continuare dopo il primo errore
  • In questo caso, rimuove i file semplici, quindi si ferma nella prima cartella
  • Non ho capito come far funzionare questo cmdlet se aggiungo il parametro UseTransaction
  • Funzionerà solo per il caso Simple (comandi che non fanno molte cose con l'ambiente attuale). Non ho testato nulla di complesso

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

Produzione:

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

Il motivo per cui non l'ho contrassegnato come soluzione è che non ho trovato il tempo di provarlo. Qualcuno ha distribuito o testato questo codice oltre all'autore?
Chuu,

0

Tutte le soluzioni di cui sopra sono fallite per me quando ho creato una directory, il che significa che mi è stato chiesto di OK ogni singola directory creata dal mio script, il che era molto. Ciò che ha funzionato per me è stato apped | Out-null per reindirizzare i risultati a Out-Null

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

Si noti che $ Directory è una stringa con il percorso completo della directory che si desidera creare. Spero che questo salvi qualcuno qualche volta: P


-1

Suggerisco due tecniche

a) Append -force

b) Append -errorAction silently continue

È così che cerco quali cmdlet supportano un determinato parametro

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

Uno dei motivi per cui ho iniziato questo percorso è che di solito voglio fare il contrario di -force, cioè qualcosa come -albackbackoff. Ho scoperto che la maggior parte dei comandi che supportano -force non sembrano avere alcuna opzione per arretrare.
Chuu,

1
A parte questo, una comoda abbreviazione di -errorAction SilentlyContinueè -ea 0.
Jay Bazuzi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.