Search code examples
windowspowershellautomationscripting

I'm not getting the expected outputs in this powershell script


i made this script in powershell, but i'm not doing something correctly (I'm trying to learn self-taught uwu)

This is the script in question.

function Get-DesiredProcess {
    $DesiredProcess=Read-Host "Welcome to de advanced task manager! Choose an action to do: 1. WUP (WindowsUpdate) 2. MDP (ProxyModification)"
    Switch ($DesiredProcess)
    {
        WUP {$ChosenProcess=Install-WUpdate}
        MDP {$ChosenProcess=Set-Proxy}
        }
    If ($DesiredProcess -eq $null) {
    Write-Error "You must specify an action!"
    return Get-DesiredProcess
    }
    Else {
    Set-Variable -Name "DesiredProcess" -Value "ChosenProcess"
    }
}

Get-DesiredProcess
Write-Output $DesiredProcess
Write-Output $ChosenProcess

The 2 last "Write-Output" are just for testing if it did registry the variables correctly or not (spoiler, it didn't)

When the Read-Host have not been answered, it should output "You specify an action!" but does nothing:

Welcome to de advanced task manager! Choose an action to do: 1. WUP (WindowsUpdate) 2. MDP (ProxyModification): 

PS C:\Users\user1\Documents\scriptsfiles> 

And when a choice is made, it should keep the variable with this part:

Set-Variable -Name "DesiredProcess" -Value "ChosenProcess"

Instead of that it executes directly the choosen process...

Thanks in advance!


Solution

  • If you want your function to set a new value to a variable defined outside the function, use scoping inside the function, so $ChosenProcess = 'Install-WUpdate' --> $script:ChosenProcess = 'Install-WUpdate'.

    However, easier to understand is to have your function output something the rest of the code can deal with. In this case, since you want both what the user typed in, AND what the chosen process for that input would be, I would suggest having the function output an object that has both properties like:

    function Get-DesiredProcess {
        # inside the function both variables have LOCAL scope
        $ChosenProcess  = $null  # initialize to nothing, or an empty string
        $DesiredProcess = Read-Host "Welcome to de advanced task manager! Choose an action to do: 1. WUP (WindowsUpdate) 2. MDP (ProxyModification)"
        switch ($DesiredProcess) {
            'WUP' {$ChosenProcess = 'Install-WUpdate'}
            'MDP' {$ChosenProcess = 'Set-Proxy'}
            default { 
                Write-Warning "You did not specify an accepted action. Type 'WUP' or 'MDP'"
                Get-DesiredProcess
            }
        }
        # only output if there is a matching chosen process
        if (![string]::IsNullOrWhiteSpace($ChosenProcess)) {
            # now have the function return both what the user typed and what the chosen action should be
            [PsCustomObject]@{
                DesiredProcess = $DesiredProcess
                ChosenProcess  = $ChosenProcess
            }
        }
    }
    
    $result = Get-DesiredProcess
    

    Using this would output something like

    Welcome to de advanced task manager! Choose an action to do: 1. WUP (WindowsUpdate) 2. MDP (ProxyModification): 7
    WARNING: You did not specify an accepted action. Type 'WUP' or 'MDP'
    Welcome to de advanced task manager! Choose an action to do: 1. WUP (WindowsUpdate) 2. MDP (ProxyModification): wup
    
    DesiredProcess ChosenProcess  
    -------------- -------------  
    wup            Install-WUpdate
    

    Now, the following code can simply act on what is in variable $result.ChosenProcess