Power shell Workflow Parameters

Hello all,

I am still new to power shell as hoping anyone could kindly assist please.

Basically I am trying to use a workflow and trying to pass arguments into the workflow as parameters. These workflow parameters will then be used as variables.

I have been reading up but can’t seem to find something out there that would match my scenario.

So as a test, I am using the below workflow example like this:

Worflow.ps1

workflow example {

 param (
   [string]$variable1,
   [string]$variable2
)

InlineScript { Write-Host $variable1 $variable2 }

}

# Call the workflow function
example

Note: this is just to test if I can pass an argument from command line into the workflow like so:

./Workflow.ps1 arg1 arg2

Hope this makes sense and looking forward to hearing from anyone soon. Again I would definitely appreciate your help. Many thanks.

Hi Linux-Pingu. What is your question? Are you having issues passing in those arguments? Is it not working?

Your example call shows passing the arguments to the .ps1 file. If that’s how you want to pass in arguments, to the actual PS1 file, then you’ll need to pass those on again to any function/workflow. Also, the inline script is ran in a different powershell scope. It’s equivalent to running a remote PS command. You can reference the calling scope’s variables with the using modifier. Test this example out and see what I mean.

param (
   [string]$scriptvariable1,
   [string]$scriptvariable2
)

Write-Host These arguments were passed into the script $scriptvariable1 $scriptvariable1 -ForeGroundColor Cyan

workflow example {

 param (
   [string]$variable1,
   [string]$variable2
)

InlineScript { Write-Host These arguments were passed into the workflow and grabbed from the calling session $using:variable1 $using:variable2 -ForeGroundColor Green }

}

# Call the workflow function
example $scriptvariable1 $scriptvariable2

Now when you call

.\workflow.ps1 first second

You should see them make it to the inline script. You should also take note that the color of the second line is not green.

Hi @krzydoug

Thank you so much for your swift response.

I edited my example workflow to match yours and can indeed see the arguements from command line passed all the way through to workflow.

However, I am still struggling to use the variables passed to workflow to be passed to a command. For example:

param (
   [string]$scriptvariable1,
   [string]$scriptvariable2
)

workflow example {

 InlineScript {
 param (
   [string]$variable1,
   [string]$variable2
)
Restart-Computer -Wait

$files = get-childitem -Recurse -path "C:\temp\folder"

# Rename content of each file in the folder using for loop
foreach ($i in $files)
   {
    $content = Get-Content $i.FullName

    $content.Replace("<AllowedSourceDomainComputers></AllowedSourceDomainComputers>","<AllowedSourceDomainComputers>O:NSG:BAD:P${variable1}${variable2}S:</AllowedSourceDomainComputers>") | Set-Content $i.FullName
   }
}
}

# Create Trigger
$Trigger = New-JobTrigger -AtStartUp

# Register the scheduled job
Register-ScheduledJob -Name ResumeWorkflow -Trigger $Trigger -ScriptBlock {[System.Management.Automation.Remoting.PSSessionConfigurationData]::IsServerManager = $true; Import-Module PSWorkflow; Resume-Job -Wait}

# Call the workflow function
example $scriptvariable1 $scriptvariable2

Basically I was tyring to get this script to replace contents of all files in a folder using for loop which will run once when computer restarts using registered schedule job. But variables are not getting inserted into file.

Thanks.

So I don’t have a lot of experience with workflows. But I do remember they have a limited set of commands that can be used. To get access to more you have to use the inlinescript like you did before.

Hi @krzydoug

Sorry i forgot to add that bit into my previous code. Just amended my previous post to reflect this. Am I still missing something?

Ahh okay so what I was missing in the workflow code was this:

$content.Replace("<AllowedSourceDomainComputers></AllowedSourceDomainComputers>","<AllowedSourceDomainComputers>O:NSG:BAD:P$using:variable_1$using:variable_2S:</AllowedSourceDomainComputers>") | Set-Content $i.FullName

However, now I need to find out how to escape the variables so that I can include the S: at the end after the 2nd variable. I was thinking something along like this?

$content.Replace("<AllowedSourceDomainComputers></AllowedSourceDomainComputers>","<AllowedSourceDomainComputers>O:NSG:BAD:P${using:variable_1}${using:variable_2}S:</AllowedSourceDomainComputers>") | Set-Content $i.FullName

But this gives me error :frowning:

You need to enclose the variables in a subexpression $(…)

$content.Replace("<AllowedSourceDomainComputers></AllowedSourceDomainComputers>","<AllowedSourceDomainComputers>O:NSG:BAD:P$($using:variable_1)$($using:variable_2)S:</AllowedSourceDomainComputers>") | Set-Content $i.FullName
1 Like

@krzydoug

Thank you so much. This helped me alot. That worked flawlessly. I also realised that you can also use back tick to achieve this.

1 Like

@krzydoug

DO you know why I am seeing this error now?

test-restart : Cannot process argument transformation on parameter 'PSParameterCollection'. Cannot convert the "(A;;GA;;;DD)" value of type "System.String" to 
type "System.Collections.Hashtable[]".
At C:\temp\local_workflow.ps1:50 char:14
+ test-restart $scriptvariable1 $scriptvariable2
+              ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [test-restart], ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,test-restart

This is now my entire code:

param(
     [string]$scriptvariable1,
     [string]$scriptvariable2
    )

## Workflow function
workflow test-restart {
   # Restart computer on workflow
   Restart-Computer -Wait
   
   # Action to perform at startup
  
    param(
     [string]$variable_1,
     [string]$variable_2
    )
      
    # Start windows forwarder service
    wecutil qc /q

    # Allow winrm to listen on port 443 as well
    echo y | cmd.exe /c winrm quickconfig -transport:https
    
    InlineScript {
    # Import event subscription event subscription xml
    $files = get-childitem -Recurse -path "C:\temp\xml"

    foreach ($i in $files)
    {
     $content = Get-Content $i.FullName

     InlineScript {$content.Replace("<AllowedSourceDomainComputers></AllowedSourceDomainComputers>","<AllowedSourceDomainComputers>O:NSG:BAD:P$($using:variable_1)$($using:variable_2)S:</AllowedSourceDomainComputers>") | Set-Content $i.FullName}

     cmd.exe /c wecutil cs $i.FullName
    }
  }
   # Unregister schedule job after restart
   Unregister-ScheduledJob -Force -Name ResumeWorkflow
}

# Create Trigger
$Trigger = New-JobTrigger -AtStartUp

# Register the scheduled job
Register-ScheduledJob -Name ResumeWorkflow -Trigger $Trigger -ScriptBlock {[System.Management.Automation.Remoting.PSSessionConfigurationData]::IsServerManager = $true; Import-Module PSWorkflow; Resume-Job -Wait}

# Call workflow function
test-restart $scriptvariable1 $scriptvariable2

If I comment this, then it works.:

#Restart-Computer -Wait

But if I uncomment it, then the error pops up.

Yes it’s treating the { ; } construct as a hash table. I should’ve offered you a different solution.

param(
     [string]$scriptvariable1,
     [string]$scriptvariable2
    )

## Workflow function
workflow test-restart {
    # Restart computer on workflow
    Restart-Computer -Wait
   
    # Action to perform at startup
  
    param(
        [string]$variable_1,
        [string]$variable_2
    )
      
    # Start windows forwarder service
    wecutil qc /q

    # Allow winrm to listen on port 443 as well
    echo y | cmd.exe /c winrm quickconfig -transport:https
    
    InlineScript {
        # Import event subscription event subscription xml
        $files = get-childitem -Recurse -path "C:\temp\xml"

        foreach ($i in $files){

            $content = Get-Content $i.FullName

            InlineScript {
                $linetoreplace = '<AllowedSourceDomainComputers></AllowedSourceDomainComputers>'
                $replacementline = '<AllowedSourceDomainComputers>O:NSG:BAD:P{0}{1}S:</AllowedSourceDomainComputers>' -f $using:variable_1,$using:variable_2
                $content.Replace($linetoreplace,$replacementline) | Set-Content $i.FullName
            }

            cmd.exe /c wecutil cs $i.FullName
        }
    }
    # Unregister schedule job after restart
    Unregister-ScheduledJob -Force -Name ResumeWorkflow
}

# Create Trigger
$Trigger = New-JobTrigger -AtStartUp

# Register the scheduled job
Register-ScheduledJob -Name ResumeWorkflow -Trigger $Trigger -ScriptBlock {[System.Management.Automation.Remoting.PSSessionConfigurationData]::IsServerManager = $true; Import-Module PSWorkflow; Resume-Job -Wait}

# Call workflow function
test-restart $scriptvariable1 $scriptvariable2

With double quotes powershell will still parse out certain items. With single quotes it’s a string literal. The -f format operator allows us to inject strings into placeholders.

1 Like

@krzydoug

Once again thank you. Still getting this error for some reason though :frowning:

test-restart : The term 'test-restart' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, 
or if a path was included, verify that the path is correct and try again.
At C:\temp\local_workflow.ps1:57 char:1
+ test-restart $scriptvariable1 $scriptvariable2
+ ~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (test-restart:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Any ideas?

I tried putting the InlineScript before the command “Restart-Computer -Wait” within workflow to see if that fixes this but no luck.

Seems like when i try to call the workflow now, it doesnt recognise it. Wondering if thats because the variables that is included when trying to call it? i.e

test-restart **$scriptvariable1** **$scriptvariable2**

Or something to do with the Restart-Computer - Wait command within the workflow? Again this only seem to work if i comment out this command within the workflow. But perhaps that is because arguments im trying to pass in gets lost when the computer does a restart

If this is the case, there must be a way to pass in aguments from command to workflow function even after a restart?