I'm trying to learn how to use Workflow in Powershell and how to get around the restrictions applied to variables (And objects in my case). But I'm facing an issue when I'm trying to modify a workflow-scope object from an InlineScript activity.
What the code does :
- Set
$VMSettingswith a Json file content. This file contains settings for VM that I want to create in Hyper-V; - Set
$VMHostSettingswith the Hyper-V host parameters; - Start a
Foreach -Parallelloop to work on each VM in parallel:- In sequence, I write the name and the path to the VM from the Workflow scope;
- In an
InlineScriptactivity, I'm writing the name of the VM with$usingas a test with how scopes work; - If
$VM.pathis empty, I'm starting a newInlineScriptactivity in which I:- Set a new variable with the content of the
$VMvariable from the workflow scope; - Change the
pathproperty of this new variable and display it;
- Set a new variable with the content of the
- I display the workflow-scope
$VM.pathagain to see if something has changed.
Here's the code:
Workflow New-VMFromJson {
$VMSettings = Get-Content -Raw -Path $ConfigurationFile | ConvertFrom-Json
$VMHostSettings = Get-VMHost
ForEach -Parallel ($VM In $VMSettings.virtualMachines) {
sequence {
'Name form Workflow: ' + $VM.name
'Path form Workflow: ' + $VM.path
InlineScript {
Write-Host "Name from InlineScript (using): $($using:VM.name)"
}
# If VM path is not set, use default Hyper-V settings instead
If (!$VM.path) {
InlineScript {
$VM = $using:VM
$VM.path = $($using:VMHostSettings.VirtualMachinePath) + 'Virtual Machines'
'Name from Inlinescript: ' + $VM.name
'Path from Inlinescript: ' + $VM.path
}
'Path form Workflow again: ' + $VM.path
}
}
}
Write-Verbose "End of Workflow"
}
New-VMFromJson -Verbose
So far, everything is good when I feed the workflow with data where $VM.path is empty (So I can enter the If block) and I get this result :
VERBOSE: 7fc31127-bee1-445f-acaa-275cc5c0c39d:[localhost]:Workflow started !
Name form Workflow: NewVM2
Name form Workflow: NewVM
Path form Workflow:
Path form Workflow:
Name from InlineScript (using): NewVM2
Name from Inlinescript: NewVM2
Path from Inlinescript: C:\Hyper-V\VM\Virtual Machines
Path form Workflow again:
Name from InlineScript (using): NewVM
Name from Inlinescript: NewVM
Path from Inlinescript: C:\Hyper-V\VM\Virtual Machines
Path form Workflow again:
VERBOSE: 7fc31127-bee1-445f-acaa-275cc5c0c39d:[localhost]:End of Workflow
We can see that everything works as it should. The InlineScript-scope modification of the new $VM variable has no impact on the workflow-scope variable of the same name and that's a normal behavior.
Now, if I want to modify the workflow-scope variable from the InlineScript activity, I get some problems. I have been following information from this Microsoft Doc page where they show this piece of code:
workflow Test-Workflow
{
$a = 3
# Changes to an InlineScript variable do not affect
# the workflow variable.
InlineScript {$a = $using:a+1; "Inline A = $a"}
"Workflow A = $a"
# To change the value in workflow scope, return the new value.
$a = InlineScript {$a = $Using:a+1; $a}
"Workflow New A = $a"
}
PS C:\> Test-Workflow
Inline A = 4
Workflow A = 3
Workflow New A = 4
So I have been changing my own code to do this instead :
If (!$VM.path) {
$VM = InlineScript {
$VM = $using:VM
$VM.path = $($using:VMHostSettings.VirtualMachinePath) + 'Virtual Machines'
Return $VM
}
}
I'm setting the workflow-scope $VM variable with the content of the InlineScript activity. In this activity, I'm still copying the content of the workflow-scope variable to a InlineScript-scope one, doing changes to the InlineScript-scope variable and then, I'm returning it.
When doing this, I get the following error :
Property 'path' cannot be found on this object; make sure it exists and is settable.
This error appears at the line corresponding to $VM = InlineScript {.
I should also mention that I get this result after running the script. Like if the workflow-scope $VM variable was erased instead of set:
VERBOSE: 7fc31127-bee1-445f-acaa-275cc5c0c39d:[localhost]:Workflow started !
Name form Workflow:
Name form Workflow:
Path form Workflow:
Path form Workflow:
Name from InlineScript (using):
Name from Inlinescript:
Path from Inlinescript:
Path form Workflow again:
Name from InlineScript (using):
Name from Inlinescript:
Path from Inlinescript:
Path form Workflow again:
VERBOSE: 7fc31127-bee1-445f-acaa-275cc5c0c39d:[localhost]:End of Workflow
Any clue on what I am doing wrong ?
$VM = $using:VM, I suspect the type is unknown, so you're trying to delve into a property that doesn't actually exist. You'll need to use$VM|Add-Member ...to add the.pathand then assign it.System.Objectwhich is fine. If I try while I'm doing the$VM = InlineScript {...}, I get nothing as if the script was even failing to enter theInlineScriptactivity..GetType()or$VM | Get-Memberto see if the object is actually being passed. Certain objects are by reference versus value and may interact differently than you expect