including instructions in a simple script

This topic contains 5 replies, has 2 voices, and was last updated by Profile photo of Rob Simmers Rob Simmers 1 year, 5 months ago.

  • Author
    Posts
  • #28067
    Profile photo of Alex Franco
    Alex Franco
    Participant

    Hello, so I'm trying to write a simple script for one of our users to restart a computer that's running a display in the lobby. The display sometimes freezes up and all we have to do is restart the compute and it loads the display on startup. So I got a simple script here:

        Param(
    
            [Parameter(Mandatory=$True)] 
            [string[]]$ComputerName
        )
    
    Invoke-Command -ComputerName $ComputerName {shutdown.exe -r -t 0} -Verbose
    pause
    

    It works just fine, but it looks like this when it's ran:

    cmdlet Restart Computer.ps1 at command pipeline position 1
    Supply values for the following parameters:
    ComputerName[0]:
    

    I'd like to get rid of the top two lines and replace it with some instructions like:

    "Type the NETBIOS name, IP address, or fully-qualified domain name of one or more computers in a comma-separated list. To specify the local computer, type the computer name, "localhost", or a dot (.). You can select multiple computers to restart. Hit enter on a blank line to continue."

    I'm still pretty new to powershell, so I don't know if this is even possible. I've tried the echo command, which ended up kinda weird; write-host didn't work; write-output I'm not sure if I used correctly, but it didn't work.

    Any help would be appreciated. Thanks!

  • #28069
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    Everything you are talking about is possible. First a couple of tips.

    1. Rather than telling them to use the default computer, you can set a default value for a parameter. [string[]]$ComputerName = $env:ComputerName
    2. While you can use invoke command to run the command locally, for something like restarting a computer, it's a bit overboard (IMHO). The shutdown command has a parameter for running the command on a remote computer (/m). Using Invoke-Command requires Powershell, remoting capabilities enabled, etc.
    3. You need to be careful asking for parameters from users, because you don't have control over what they put in and usually have to put extra code in to make sure they are doing things correct. Take a look at ValidateSet, you can allow only certain computers to be passed to the computername parameter.
    4. Also, take a look at Restart-Computer, which is the Powershell version of Shutdown.exe.

    Possibly try something like this so that you can control which computers they can restart, which also will require they have administrative rights to restart the computer:

    param(
    [ValidateSet("localhost","Computer1","Computer2")] 
    [String] 
    $ComputerName 
    )
    
    Restart-Computer -ComputerName $ComputerName -Force
    
  • #28073
    Profile photo of Alex Franco
    Alex Franco
    Participant

    Wow, that is awesome. A lot of very good points and advice. I should've looked for a specific Restart-Computer command instead of trying to use what I already knew, that would've simplified things a lot. I think I'll take your recommendation, with the addition of a mandatory parameter and a -verbose switch. Here's the the script running through it's completion

    cmdlet Restart Computer.ps1 at command pipeline position 1
    Supply values for the following parameters:
    ComputerName: [REDACTED]
    VERBOSE: Performing operation "Enable the Remote shutdown access rights and restart the computer." on Target
    "[REDACTED]".
    Press Enter to continue...:
    

    It runs successfully and is a much better solution than what I had started with, but I'd still like to include that instruction set. Ideally, I'd like it to look like this

    Type the NETBIOS name, IP address, or fully-qualified domain name of one or more computers in a comma-separated list. To specify the local computer, type the computer name, "localhost", or a dot (.).
    
    Supply values for the following parameters:
    ComputerName: [ComputerName]
    VERBOSE: [whatever it's say with a verbose tag] 
    Press Enter to continue...:
    

    Again, any help is greatly appreciated! Thank you

  • #28074
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    Take a look at something like:

    $ComputerName = Read-Host -Prompt "Type the NETBIOS name, IP address, or fully-qualified domain name of one or more computers in a comma-separated list."
    
  • #28077
    Profile photo of Alex Franco
    Alex Franco
    Participant

    Forgive my ignorance, but how is that intended to be used? I've tried a number of ways of implementing it. Before the param:

    $ComputerName = Read-Host -Prompt "Type the NETBIOS name, IP address, or fully-qualified domain name of one or more computers in a comma-separated list."  
     
         param(
            [Parameter(Mandatory=$True)]
            [ValidateSet("REC-WS07BS229")] 
            [String] 
            $ComputerName 
            )
    
    Restart-Computer -ComputerName $ComputerName -Force -Verbose
    

    Gives an error about the param being unknown. After the param:

       param(
            [Parameter(Mandatory=$True)]
            [ValidateSet("REC-WS07BS229")] 
            [String] 
            $ComputerName 
            )
    
    $ComputerName = Read-Host -Prompt "Type the NETBIOS name, IP address, or fully-qualified domain name of one or more computers in a comma-separated list."  
    
    Restart-Computer -ComputerName $ComputerName -Force -Verbose
    

    This will output it, but not the way it's intended. It that will output:

    cmdlet Restart Computer.ps1 at command pipeline position 1
    Supply values for the following parameters:
    ComputerName: [REDACTED]
    Type the NETBIOS name, IP address, or fully-qualified domain name of one or more computers in a comma-separated list.: 
    Restart-Computer : Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Supply an argument that is not null or empty and then try the 
    command again.
    At C:\Users\alex.franco\Documents\Batch Programs\Restart Computer.ps1:10 char:32
    + Restart-Computer -ComputerName $ComputerName -Force -Verbose
    +                                ~~~~~~~~~~~~~
        + CategoryInfo          : InvalidData: (:) [Restart-Computer], ParameterBindingValidationException
        + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RestartComputerCommand
    

    It displays the text after the initial computer name prompt, so it's not much use for instructions. I tried just putting in the variable and piping it to the rest of the command like so:

       param(
            [Parameter(Mandatory=$True)]
            [ValidateSet("REC-WS07BS229")] 
            [String] 
            $ComputerName 
            )
    
    $ComputerName = Read-Host -Prompt "Type the NETBIOS name, IP address, or fully-qualified domain name of one or more computers in a comma-separated list."  
    
    $ComputerName | Restart-Computer -ComputerName $ComputerName -Force -Verbose
    

    And this does the same thing as the previous option. I also tried renaming the variable you gave me to $prompt in case in case there was some conflict with the parameter and variable. Don't rightly know what else i can do with it

    Any help is appreciated! Thanks again

  • #28079
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    You are mixing and matching many things. Explain how you would like it to work.You seem like you are trying to make one thing work for many different scenarios, which is fine. However, the use case is you want to give a user a quick and easy way to restart the lobby computer. If the user knows the computername, he can just simply tell the user to open Powerhsell and type:

    Restart-Computer REC-WS07BS229
    

    You could save that to a script and they could run the script if you think knowing the computer is too much.

You must be logged in to reply to this topic.