none
PowerShell: the Begin, Process, and End blocks are all skipped when executing my first [simple] script RRS feed

  • Question

  • I am learning PowerShell and have written my first script, a twenty line, one page script (after reading through Ed Wilson's First Steps, Step-by-Step, and then the Deep Dives book). Surprisingly, no line of my script executes, yet no error message appears and the $Error variable is empty. Following the best practices suggested in "Deep Dives" the script was created by the ISE Editor's Snippets "Cmdlet (Advanced function)" template.

    Placing the cursor on each curly brace shows its matching brace exists and is in the correct place. The comment lines are highlighted in Green by the ISE Editor, so I can see that I have not inadvertently commented out my entire script :)

    Placing a Write-Host cmdlet in the Begin and End Blocks produced no pop-up window. Setting a Breakpoint on the first executable line of the script failed to pause the code at that line (though the line was highlighted in brown by the ISE editor). Opening the ISE console in Administrator mode had no effect. Issuing Set-PSDebug -Step merely asked permission (Yes/No) to execute the script then completed without pause. Listing the Script Execution Policy showed "RemoteSigned" for LocalMachine and Undefined for all other scopes on my Windows 8.1 computer. Setting the policy scope for CurrentUser to "RemoteSigned" was successful but did not cause the script's code to execute.

    What step am I missing to cause the code within my script to execute?


    Jeffrey - New Orleans MCITP Enterprise Administrator, Virtualization Administrator

    Wednesday, September 10, 2014 3:48 PM

Answers

  • If you used the advanced function template from the ISE, then you've created a function, and executing that code isn't going to actually output anything - all you've done is define a function.  

    The code within that function isn't going to run until you invoke the function.


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    Wednesday, September 10, 2014 4:02 PM
    Moderator

All replies

  • Please post a short repro case (small script containing only minimum amount of code needed to reproduce the problem and the ISE steps you are taking that are not working as expected). Also tell what you were expecting to happen and what happened instead. (Remember, we can't read your mind, we don't have a copy of your script, and we can't see your screen.)

    -- Bill Stewart [Bill_Stewart]

    Wednesday, September 10, 2014 3:55 PM
    Moderator
  • If you used the advanced function template from the ISE, then you've created a function, and executing that code isn't going to actually output anything - all you've done is define a function.  

    The code within that function isn't going to run until you invoke the function.


    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    Wednesday, September 10, 2014 4:02 PM
    Moderator
  • Hi,

    Are you actually running your new function somewhere? Just pressing the Run button in the ISE won't actually cause the function to run.

    As an example, here's the same template you've mentioned (pared down):

    function Test-Example {
    
        [CmdletBinding()]
        [OutputType([int])]
        Param
        (
            # Param1 help description
            [Parameter(Mandatory=$true,
                       ValueFromPipelineByPropertyName=$true,
                       Position=0)]
            $Param1,
    
            # Param2 help description
            [int]
            $Param2
        )
    
        Begin {
    
            Write-Output "In Begin - Param1 is $Param1"
    
        }
    
        Process {
    
            Write-Output "In Process - Param1 is $Param1"
    
        }
        
        End {
    
            Write-Output "In End - Param1 is $Param1"
    
        }
    
    } # End Test-Example function
    
    Test-Example -Param1 'Some Text Goes Here'


    EDIT: Slow on submit, see above.

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

    Wednesday, September 10, 2014 4:03 PM
  • Being new to PowerShell (my last programming language was LISP), I thought I might have not performed some fundamental step required to execute a PowerShell script, but a few have asked to see the script code, as displayed in the ISE Editor.

    <#
    
    .Synopsis
       On target computers, this script sets the Windows Registry value of the Screen Saver Timeout.
    .DESCRIPTION
       On target computers, this script sets the Windows Registry value of the Screen Saver Timeout. By default, it will assume the target is the local computer
            itself and the timeout is 3,600 seconds (one hour).
    .EXAMPLE
       Set-ScreenSaverTimeout -ComputerName DC1, FS1, FS2 -TimeOutSeconds 900                       ; three computer's screensaver times out at 900 seconds
    .EXAMPLE
       Set-ScreensaverTimeout                                                                       ; the local computer's screensaver times out at 3600 seconds
    #>
    function Set-ScreenSaverTimeout {
    
        [CmdletBinding()]
        
        Param
        (
            # Parameter 0 holds the names of the target computers for this script
            [Parameter(Mandatory=$true,
                       ValueFromPipelineByPropertyName=$true,
                       Position=0)]
            $ComputerName = $env:COMPUTERNAME,
    
            # Parameter 1 holds the number of idle seconds before the screen saver timeout is invoked on the target computer
            [Parameter (Mandatory=$true, Position=1)]
            [int]
            $TimeOutSeconds = 3600
        )
    
        Begin {
            Write-Host {"Starting setting screen saver timeout to $TimeOutSeconds on $ComputerName.count target computers(s)"}
            }
        Process {                                                           # examine each target computer, one at a time
            Write-Host {"Starting setting screen saver timeout to $TimeOutSeconds on target computer $ComputerName.name"}
    
            $RegKeyPath = "HKCU:\Software\Policies\Microsoft\Windows"
    
            If (Test-Path ($RegKeyPath + "\Control Panel")) {				# if the Control Panel hive exists, append it to our Registry Key File Path
                $RegKey = "HKCU:\Software\Policies\Microsoft\Windows\Control Panel"
    
                If (Test-Path ($RegKeyPath + "\Desktop")) {				    # if the Desktop hive exists, append it to our Registry Key File Path
                    $RegKey = "HKCU:\Software\Policies\Microsoft\Windows\Control Panel\Desktop"
    
                    New-ItemProperty -path $RegKeyPath -name ScreenSaveTimeOut -value $TimeOutSeconds -PropertyType String -Force
                    }
    
                Else {
                    New-Item -path $RegKey -name Desktop			        # create the Desktop hive then append it to our Registry Key File Path
                
                    $RegKeyPath = "HKCU:\Software\Policies\Microsoft\Windows\Control Panel\Desktop"
                    New-ItemProperty -path $RegKeyPath -name ScreenSaveTimeOut -value $TimeOutSeconds -PropertyType String
                    }
                }
    
            Else {										                    # create the Control Panel hive then append it to our Registry key
                New-Item -path $RegKeyPath -name Control Panel
                $RegKeyPath = "HKCU:\Software\Policies\Microsoft\Windows\Control Panel"
    
                New-Item -path $RegKeyPath -name Desktop				        # create the Desktop hive then append it to our Registry key
                $RegKeyPath = "HKCU:\Software\Policies\Microsoft\Windows\Control Panel\Desktop"
    
                New-ItemProperty -path $RegKeyPath -name ScreenSaveTimeOut -value $TimeOutSeconds -PropertyType String
                }
    
            }
    
        End {
            Write-Host {"Completed setting screen saver timeout to $TimeOutSeconds on $ComputerName.count target computers(s)"}
            }
        }


    Jeffrey - New Orleans MCITP Enterprise Administrator, Virtualization Administrator

    Wednesday, September 10, 2014 4:22 PM
  • Yep, you're not actually running your function.

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

    Wednesday, September 10, 2014 4:24 PM
  • So, as the other respondents noted, you have defined a function.

    You have to execute the function for the code to run.


    -- Bill Stewart [Bill_Stewart]

    Wednesday, September 10, 2014 4:24 PM
    Moderator
  • From the command line in the ISE PowerShell console window, I am issuing

    PS C:> $myPC = $env:ComputerName

    PS C:> C:\Scripts\Set-ScreenSaverTimeout.ps1 -ComputerName $myPC -TimeOutSeconds 900

    I don't get any error message, but is that syntax wrong?


    Jeffrey - New Orleans MCITP Enterprise Administrator, Virtualization Administrator

    Wednesday, September 10, 2014 4:27 PM
  • Drop the .ps1 extension and use the function name only. It should be available after you've hit the Run button in the ISE once.

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

    Wednesday, September 10, 2014 4:29 PM
  • If the script file Set-ScreenSaverTimeout.ps1 contains that function, then you are running the script, which defines the function, then exits. That doesn't run the function.

    You can do one of two things:

    1. Add a line of code to the bottom of your script file that executes the function. (See Mike Laughlin's example, at the bottom.)

    2. Change the script file so that it doesn't define the function and instead starts running the code. To do this, remove the Function line and its closing curly brace.


    -- Bill Stewart [Bill_Stewart]

    Wednesday, September 10, 2014 4:31 PM
    Moderator
  • Yes, loading the script into the ISE console window, pressing the Run button, then typing just the function name & parameters in the PowerShell console window caused the code to execute (with a few errors I will troubleshoot).

    To allow ordinary users to execute this script from a local command prompt (assuming I have pushed out the script to their remote computer), how do I get the script to first load then execute? Do they simply need to type C:> powershell.exe C:\Scripts\Set-ScreenSaverTimeOut.ps1 ?


    Jeffrey - New Orleans MCITP Enterprise Administrator, Virtualization Administrator

    Wednesday, September 10, 2014 4:52 PM
  • You can use dot sourcing if you want to keep your function:

    http://mctexpert.blogspot.com/2011/04/dot-sourcing-powershell-script.html

    Alternatively, follow Bill's suggestion #2 above.


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

    Wednesday, September 10, 2014 4:57 PM
  • All these prompt replies have been most help -- thanks, everyone for help in getting me started!

    If I add a line at the bottom of the script (past the curly brace that ends the function definition), would I have to include specific values for the function's parameters, which would remove flexibility?


    Jeffrey - New Orleans MCITP Enterprise Administrator, Virtualization Administrator

    Wednesday, September 10, 2014 4:58 PM
  • I was concerned that dot sourcing would make the function's internal variables become [needlessly] global in scope (for the console session), so I will test Bill's suggestion #2.

    Jeffrey - New Orleans MCITP Enterprise Administrator, Virtualization Administrator

    Wednesday, September 10, 2014 5:01 PM
  • All these prompt replies have been most help -- thanks, everyone for help in getting me started!

    If I add a line at the bottom of the script (past the curly brace that ends the function definition), would I have to include specific values for the function's parameters, which would remove flexibility?


    Jeffrey - New Orleans MCITP Enterprise Administrator, Virtualization Administrator

    Adding that line would simply be a way to test the function.  It won't "remove flexibility", because it's not changing anything in the function. You'd want to remove it after you're done testing.

    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

    Wednesday, September 10, 2014 5:12 PM
    Moderator
  • I would recommend that if you really need to configure the screen saver timeout for multiple users, you should use group policy (of course, disregard if you are just using this as a learning exercise).


    -- Bill Stewart [Bill_Stewart]

    Wednesday, September 10, 2014 6:36 PM
    Moderator