none
Having trouble with the Read-Host cmdlet not actually waiting for the user input before moving to the next line in the script. RRS feed

  • Question

  • Hi

    I fairly new to this, and I have the following commands working perfectly in the ISE.  Problem is, if I run this in the power shell console (Windows 7), which is what happens when you double click the file, it runs, but it blasts right past the Read-host commands.  In ISE it stops and waits for the input.  Any help?  And feedback on th other suff?  Remember I'm a newbie, be gentle.

    #Draft Powershell Script to streamline xxx to yyy migration and reduce the key entry required.  This MUST be run as an administrator or it will fail to configure the IP stack.   
    #Version 1.0 - Lee Buskey
    Set-ExecutionPolicy RemoteSigned
    # stuff variable with the current machines hostname.
    $hostname = hostname
    #Stuff variable to the migration data text file. 
    $migrationdata = '"c:\migrate\IPDATA.txt"'
    # Define the "IP" variable, Read in the master migration data from a text file, and find the line that matches the hostname and stuff it in the variable. 
    $ip = Select-String -Path "C:\migrate\IPDATA.txt" -Pattern $hostname
    # Convert the IP variable contents to a text string value
    $ip = $ip.ToString()
    #Lop off the first 35 Characters of the IP variable to get rid of junk.   
    $ip = $ip.Substring(35)
    #Trim off any leading spaces.. 
    $ip = $ip.Trim()
    #Still working on code to conditinally ask this question if the hostname is not found in the data file. 
    #$ip = Read-Host “Please enter the IP address for this machine. (xxx.xxx.xxx.xxx.)”
    #Populate the DNS server variable
    $dns = “10.10.1.10”,”10.10.1.11”
    #Populate the Gateway variable
    $gateway = “10.10.4.1”
    #Populate the Netmask variable
    $netmask = “255.255.252.0”
    #Populate the DNS suffix variable
    $dnsdomain = “new.domain.local”
    #clear the screen
    cls
    #show the user what the script is about to do
    Write-Output ("We will be using the following information for the new IP stack","","Hostname:", $hostname,"","IP address","$Ip","","Default Gateway:", $Gateway,"","DNS Servers:", $DNS,"","DNS Suffix:",$DNSdomain,"","")
    #Ask the user to confirm the data, or give an option to exit. 
    $Config = Read-Host “Please press enter if this is correct, and we will apply this configuration. or CTRL-C to exit"
    #configure the Ip stack
    $Interface = Get-WmiObject win32_networkadapterconfiguration -filter "ipenabled = 'true'"
    $Interface.EnableStatic($ip, $netmask)
    $Interface.SetGateways("$Gateway", 1)
    $Interface.SetDNSServerSearchOrder($dns)
    $Interface.SetDNSDomain($dnsdomain)
    $Interface.SetDynamicDNSRegistration(“TRUE”)
    #Show the user the new IP configuration
    ipconfig /allcompartments /all
    #add a few line feeds to the screen
    Write-Output ("","","")
    #Still wroking on code to go here to verify connectivity to new DNS servers before proceeing.  May not be necessary..
    #Ask the user of the new config looks right, give an option to exit before trying to join domain.
    $Config = Read-Host “We have reconfigured the NIC.  Does the IP configuration for the "Local Area Connection" look right?  Press enter to continue to join the domain, or CTRL-C to exit”


    • Edited by Lee Buskey Friday, October 17, 2014 6:14 PM
    Friday, October 17, 2014 6:14 PM

Answers

  • Closer look:


    $config = Read-Host "Press a key"
    Write-Host "I'm done"
    

    What's going to happen is that PowerShell will prompt, but the input for the prompt will come from the next line pasted to the console. So the $config variable will actually contain the string 'Write-Host "I'm done"'.

    Like David pointed out, copy and paste into the console window will not behave like you are expecting because the console input queue isn't going to stop reading input lines when you paste. It is working as designed, but not like you expected.


    -- Bill Stewart [Bill_Stewart]

    • Marked as answer by Lee Buskey Tuesday, October 21, 2014 1:15 PM
    Monday, October 20, 2014 5:00 PM
    Moderator
  • Here's one method:

    $found = $false
    
    do {
    
        If (Test-Connection -ComputerName ComputerName -Count 1 -Quiet) {
    
            $found = $true
    
        } Else {
    
            Start-Sleep -Seconds 10
    
        }
    
    } Until ($found)
    
    # Do stuff


    Don't retire TechNet! - (Don't give up yet - 13,085+ strong and growing)

    • Marked as answer by Lee Buskey Tuesday, October 21, 2014 1:47 PM
    Tuesday, October 21, 2014 1:25 PM

All replies

  • Double clicking on a .ps1 file shouldn't run it, it should only open it up in Notepad (unless you've changed the default behavior, of course).

    What happens if you run the file in the console manually?

    You may be having problems with smart quotes, make sure that all double quotes are proper " characters and not .


    Don't retire TechNet! - (Don't give up yet - 13,085+ strong and growing)

    Friday, October 17, 2014 6:33 PM
  • Thanks for the reply.  My mistake.  When I right click it and select "Run with with PowerShell".  If I paste the txt right into the Power Shell window (Not ISE) I get the same behavior, just passes right by the get-host statement. 

    The text cam out of Notepad, and I only have one quotes key.  How could I have that wrong?

    Lee

    Friday, October 17, 2014 7:18 PM
  • Thanks for the reply.  My mistake.  When I right click it and select "Run with with PowerShell".  If I paste the txt right into the Power Shell window (Not ISE) I get the same behavior, just passes right by the get-host statement. 

    The text cam out of Notepad, and I only have one quotes key.  How could I have that wrong?

    Lee

    You must have copied it from somewhere. This happens a lot when grabbing code from webpages.

    I just pasted the line into Notepad++ and can confirm that the first quote is a smartquote, not a regular quote.


    Don't retire TechNet! - (Don't give up yet - 13,085+ strong and growing)

    Friday, October 17, 2014 7:23 PM
  • I can simplify this problem.   If I do this:

    $Config = Read-Host "Press a key”
    $config
    Write-host "I'm done"

    I get the same problem.  I'd post a couple of pics, but the system still thinks I am unverified for some reason. 

    I am sure I am doing something silly.   Does one need to configure the powershell environment before doing commands like this?  All I do is keep the defaults, and set the execution policy to remote signed. 



    • Edited by Lee Buskey Friday, October 17, 2014 7:38 PM
    Friday, October 17, 2014 7:35 PM
  • I can't replicate your issue:


    EDIT: As for not being able to post screenshots, check this forum for a sticky verification thread that you can post in to get your account verified:

    https://social.technet.microsoft.com/Forums/en-US/home?forum=reportabug


    Don't retire TechNet! - (Don't give up yet - 13,085+ strong and growing)

    Friday, October 17, 2014 7:38 PM
  • Thanks.. So I am working on a machine thats been secured to DOD standards.  This sometimes mandates changes to default behavior.  I'd have to screen the STIG to see if Powershell is in there.   In the meantime, I can try it on my home PC and see what I get.   Thanks.

    Friday, October 17, 2014 7:57 PM
  • Out of curiosity, what do you see in the registry under HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\0\Command ?  Maybe your file associations have been tweaked, and you're running the script with the -NonInteractive switch.  (Kind of grasping at straws there, but Read-Host doesn't work in conjunction with -NonInteractive.)

    Friday, October 17, 2014 8:09 PM
  • Nope, but good one.. Here what we have:

    "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-file" "%1" "-Command" "if((Get-ExecutionPolicy ) -ne AllSigned) { Set-ExecutionPolicy -Scope Process Bypass }"

    Monday, October 20, 2014 3:51 PM
  • Here's what I get on a stand alone, fresh out of the box and patched Windows 7 box.  No policy or anything..

    The text I pasted in the shell was:

    $config = Read-Host "Press a key"
    Write-host "I'm done"
    $config

    I never got a chance to press a key..


    • Edited by Lee Buskey Monday, October 20, 2014 4:12 PM
    Monday, October 20, 2014 4:12 PM
  • What happens if you save that as a script file and execute it?

    Don't retire TechNet! - (Don't give up yet - 13,085+ strong and growing)

    Monday, October 20, 2014 4:15 PM
  • When you're copying and pasting code into the console, you essentially have "pressed a key" as far as PowerShell is concerned.  (The newline after the Read-Host call.)  As Mike mentioned, saving that as a script and running it should work fine.

    You can make it work with copy / paste by pasting in one large line with semicolons separating the spaces, but that's a bit weird:

    $config = Read-Host "Press a key"; Write-host "I'm done"; $config

    Monday, October 20, 2014 4:51 PM
  • Closer look:


    $config = Read-Host "Press a key"
    Write-Host "I'm done"
    

    What's going to happen is that PowerShell will prompt, but the input for the prompt will come from the next line pasted to the console. So the $config variable will actually contain the string 'Write-Host "I'm done"'.

    Like David pointed out, copy and paste into the console window will not behave like you are expecting because the console input queue isn't going to stop reading input lines when you paste. It is working as designed, but not like you expected.


    -- Bill Stewart [Bill_Stewart]

    • Marked as answer by Lee Buskey Tuesday, October 21, 2014 1:15 PM
    Monday, October 20, 2014 5:00 PM
    Moderator
  • Can you show what was in your script?

    Monday, October 20, 2014 5:45 PM
  • Can who show what was in what script?

    -- Bill Stewart [Bill_Stewart]

    Monday, October 20, 2014 5:50 PM
    Moderator
  • My bad. I replied to the wrong person....
    Monday, October 20, 2014 10:54 PM
  • I see. This Makes sense, but I am pretty sure I became aware of the issue the first time I ran it as a script. I'll try again though . I'd hate to be chasing my tail here. Thanks for the time and suggestions... Can you recommend and approach where I end up with a text copy on the local drive of all the script output? But still prompting the user when it's supposed to?
    Monday, October 20, 2014 10:58 PM
  • If you're in powershell.exe (as opposed to the ISE or any other host), you can use the Start-Transcript command for that. In PowerShell v5, Start-Transcript will be supported in any host, which is a nice change.

    Tuesday, October 21, 2014 1:32 AM
  • Perfect.  there was never anything wrong with my script, just with the way I was testing it!  Thanks guys, 
    Tuesday, October 21, 2014 1:16 PM
  • Thanks, this is just what I needed..

    Tuesday, October 21, 2014 1:16 PM
  • FInal quick question for you guys.  I know I am close.  I am looking to make a loop that will test for connectivity to a domain controller continuiously until it sucseeds, then joins the domain..  

    So Far I have:

    if (Test-Connection -ComputerName dc09 -Authentication Default -BufferSize 16 -Count 1 -quiet) { Add-Computer -DomainName domain.local

    -OUPath "OU=Desktops,DC=domain,DC=local" -Restart -ErrorAction Inquire } else {test again}

    Not sure how I make this a loop though..

    



    • Edited by Lee Buskey Tuesday, October 21, 2014 1:21 PM
    Tuesday, October 21, 2014 1:20 PM
  • Here's one method:

    $found = $false
    
    do {
    
        If (Test-Connection -ComputerName ComputerName -Count 1 -Quiet) {
    
            $found = $true
    
        } Else {
    
            Start-Sleep -Seconds 10
    
        }
    
    } Until ($found)
    
    # Do stuff


    Don't retire TechNet! - (Don't give up yet - 13,085+ strong and growing)

    • Marked as answer by Lee Buskey Tuesday, October 21, 2014 1:47 PM
    Tuesday, October 21, 2014 1:25 PM
  • If test passes, set $found = $true  (where did the variable $true come from?)

    $true is builtin, that's how you set a boolean to true. Basically I'm undoing setting $found to false, which would allow the do loop to complete.

    if not, sleep for 10 seconds.. Then what?

    Then it tries the if test again. It'll continue to loop until $found is set to $true. This could cause an infinite loop.


    Don't retire TechNet! - (Don't give up yet - 13,085+ strong and growing)

    Tuesday, October 21, 2014 1:39 PM
  • I think I figued it out.   Really have to change the way I think about processes....

    Thanks for the help...

    Tuesday, October 21, 2014 1:47 PM