18

I have a script I am using to automate WSUS processes, and the last stage of it goes on to remove all old/unnecessary files/objects.

I would like to prompt 'Press 'Enter' to continue with removal or any other key to stop' before the cleanup stage to give people the option to not run it.

The code I currently have at the end of the script is here:

Get-WsusServer 10.1.1.25 -PortNumber 8530 | Get-WsusUpdate -Classification All -Approval Unapproved -Status FailedOrNeeded | Approve-WsusUpdate -Action Install -Target $ComputerTarget -Verbose

Write-Host "Updates have been approved!"
Write-Host "Preparing to clean WSUS Server of obsolete computers, updates, and content files."

#Part2 - WSUS Server Cleanup

##Run Cleanup Command
Get-WsusServer $WSUS_Server -PortNumber $PortNumber | Invoke-WsusServerCleanup -CleanupObsoleteComputers -CleanupObsoleteUpdates -CleanupUnneededContentFiles

Just prior to #Part2 I would like to have the prompt 'Press enter to continue or any other key to abort'

Is there a simple way to do this?

Everything I've seen appears to involve nesting the entire script inside of a code block which I'd rather not do. =/

8 Answers 8

16

Another simple solution would be to use:

Read-Host -Prompt "Press any key to continue or CTRL+C to quit" | Out-Null

I believe this is a better solution to the currently accepted answer because the requirement of hitting enter on the keyboard. I don't believe hitting enter will accept the UI prompt unless that UI element is in focus.

18

You Can use write-warning option. quite sleek:

Write-Warning "This is only a test warning." -WarningAction Inquire
WARNING: This is only a test warning.
Confirm
Continue with this operation?
 [Y] Yes  [A] Yes to All  [H] Halt Command  [S] Suspend  [?] Help (default is "Y"):
2
  • Cheers mate, that a very neat way of doing it!
    – Stuggi
    May 15, 2020 at 7:39
  • I think this is neat, but A keeps asking the question if there are multiple of these in a script. How would you have A (Yes to All) apply to all the answers?
    – Tolga
    Apr 13, 2021 at 1:02
5

Just add -confirm to your Invoke-WsusServerCleanup command. It's built in.

3
  • 1
    I....oh....wow....uh....yeah. That's a great idea. Looking at parameters might have value? Oops!
    – Abraxas
    Sep 3, 2015 at 19:06
  • I thought about mentioning -confirm in my answer but you were specific in your question. If all you want is a prompt then this is the best answer.
    – Jim B
    Sep 3, 2015 at 19:28
  • The original cause for the question was the ability to satisfy an 'approve next step' option and I like the added benefits of writing to a variable and then if statement check. That being said, were I just back working on the script I wouldn't have posted if I knew about this. Thanks for all of the great answers though.
    – Abraxas
    Sep 3, 2015 at 20:53
2

See Pausing a Script Until the User Presses a Key

The relevant script lines are:

Write-Host "Press enter to continue and CTRL-C to exit ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

You can add a check for enter and wrap this is a loop if you really really want just one key to continue. You can also add an else to exit the script but I'd recommend just reminding the user that ctrl-c will exit. Why code for something that's built in.

3
  • That's awesome, but I would like to learn how to do a check for 'enter' or even, at some point do something like 'a for yes to all' 'y for yes' 'n for no' 'c for cancel' Are there any articles which detail best practices for this? I'm just getting in to PowerShell scripting and seem to be finding needlessly complex options.
    – Abraxas
    Sep 3, 2015 at 17:07
  • Its going to be an If statement on the $x variable. There isn't a "best practice" for if statements, but a search for "powershell if" can give you the syntax. Its worth the effort to make an attempt then post if you can't get the "If" to work.
    – Jim B
    Sep 3, 2015 at 18:03
  • It doesn't allow CTRL-C to exit as pressing down CTRL (yet without C) already confirms and thus continues the execution. Tested in PowerShell 5 and 7.
    – boernsen
    Mar 7 at 10:14
2

At whatever step you'd like PowerShell to hold at, write Pause in your code. PowerShell will sit at "Press Enter to continue...:" until you hit Enter or close the shell/ISE.

1

You could insert a Read-Host cmdlet and then process the input value the way you want.

$userInput = Read-Host 
0
1

Building this answer just as a follow-up add-on based on the OPs comment about how to validate input, as an addition to the other good answers.. It was too long to put into a comment at the right place.

Validating input can be done in several ways. By way of personal preference I like using the switch statement for input validation, as I generally find it easier to read and debug than a bunch of if elses and more versatile than a do while.

Similarly I prefer using functions over loops for failing the validation, as I find the code cleaner and more reusable. Functions also have the built in possibility of parameter validation where that seems like the best way of validating the content of a variable.

So just as an example, here is a simple function which calls itself to restate the question when the input is not as expected.

function Get-SomeInput {
    $input = read-host "Please write yes or no and press Enter"

    switch ($input) `
    {
        'yes' {
            write-host 'You wrote yes'
        }

        'no' {
            write-host 'You wrote no'
        }

        default {
            write-host 'You may only answer yes or no, please try again.'
            Get-SomeInput
        }
    }
}

Get-SomeInput
6
  • Turning this into a function is overkill. This answer isn't wrong or bad, just overcomplicated.
    – Jim B
    Sep 3, 2015 at 19:30
  • 1
    I don't neccessarily agree at all @Jim, it's a reusable way of iterating code = less code. It's all about circumstance and imagination. But don't forget, The OP asked how to validate in a comment, a case of where the switch statement excels.
    – ErikE
    Sep 3, 2015 at 19:53
  • We'll have to agree to disagree. We're not developing applications, so there isn't a lot of reuse of a function that replaces a whopping 3 lines of top of head code,it also breaks the powershell develop as you write model of script creation. It's certainly useful to have a repository of code for things you've had to figure out that were complicated- an if statement isn't one of them IMHO
    – Jim B
    Sep 4, 2015 at 3:51
  • Yes @Jim, I put it down to personal preference. I find neither complicated but this easier to read - the value being evaluated kind of hops out to the eyes. You're wrong about the 3 lines when using an if-else though, the point is to create a loop which you'd spend a couple more lines doing too (I did a function for it). If you use my preferred way of formatting 'spreading your wings' to sacrifice vertical space for greater readability you'd get more lines too. The big win is that I can concentrate my program flow to very few lines for when debugging, in this case one line with one command.
    – ErikE
    Sep 4, 2015 at 4:20
  • If you want code reuse create a snippet. I think its bad practice to create scripts with profile dependencies or worse yet buckets of function declarations. I appreciate the candor and it gives me some class ideas as well.
    – Jim B
    Sep 8, 2015 at 4:57
1

I completely agree with the currently accepted answer. Using Read-Host is a great way to add that user-friendly touch, giving users the option to proceed or halt the process.

But if someone's looking for even more control over the user interaction, a [switch] statement could be a nifty tool for handling different inputs. Just a little extra tip for those who want to take it a step further.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .