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
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
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?