Caveat Lector: I’m
not a WFA expert so this might be a rubbish post. Please feel free to comment
below if you disagree, or to tell me I’ve got this wrong.
In the previous
post using row repetition in WFA to create 10 CIFS shares it took:
7
minutes 7 seconds - using the PowerShell
version of the Create CIFS Share command
0 minutes
26 seconds - using the Perl version
of the Create CIFS Share command
And then creating 10 CIFS shares just from the PowerShell
CLI, it took only 13
seconds.
Q: So, why is WFA
and PowerShell so slow?
A: The answer is because every PowerShell command in WFA
is run in a brand new PowerShell instance, which means you’re loading the profile.ps1
and everything that’s inside it, for every single PowerShell command you run.
In my example of creating 10 CIFS shares using the ‘Create CIFS Share’ command
with row repetition, we were using 10 different PowerShell instances and each
one had to wait for profile.ps1 and everything inside it to load - no wonder it
was slow!
Note: If you don’t
believe me, edit the file C:\Program
Files\NetApp\WFA\PoSH\profile.ps1 with a line like the below at the end -
Date >> C:\TEMP\WFA_Profile.log
- then run your
workflow and see how many times the date is logged.
Q: Is there a way
to improve PowerShell performance with WFA?
A: I don’t do enough with WFA to offer a built solution. Personally
I’d probably just use Perl rather than start messing around with WFA and
perhaps putting it in an unsupported state, but this is what I’d consider
doing:
i) Re-engineer the commands so that all required code is saved
into a temporary PS1 file. Also make a note of which cmdlets we’re actually
using, so we only need to ‘Import-Module DataONTAP -Cmdlet ...’ the cmdlets we
actually need.
ii) Have a simple command to optimize profile.ps1 for
loading the code
iii) Have a simple command to optimize profile.ps1 for
running the code
iv) Have a simple command to execute the code
Then we run a workflow that’s something like this (before
running the workflow we’ve already optimized profile.ps1 for loading code):
1) Compile all the commands into the temporary PS1 file
2) Optimize profile.ps1 for running code
3) Execute the temporary PS1 file
4) Optimize profile.ps1 for loading code
Step 1 is pretty much an “original” workflow, just with
our modified commands. Steps 2, 3 and 4 are the additional elements.
Note: This method would
likely break some WFA functionality, so it’s definitely not recommended.
APPENDIX: OnCommand Workflow Automation 4.1’s
C:\Program Files\NetApp\WFA\PoSH\profile.ps1
$POSHDir
= split-path $MyInvocation.MyCommand.Path
$ModulesDir
= "$POSHDir\Modules"
#Adding
assemblies
$assemblies
= @()
$dlls=(Get-ChildItem
-Path $ModulesDir -Filter *.dll)
foreach
($dll in $dlls) {
Add-type -path "$ModulesDir\$dll"
-ErrorAction SilentlyContinue
$assemblies +=$dll.Name
}
#Adding
modules
$files=(Get-ChildItem
-Path $ModulesDir)
foreach
($file in $files) {
if ($assemblies -contains $file.Name){
#"this is an assembly... skip it"
continue
}
Import-Module "$ModulesDir\$file"
-ErrorAction SilentlyContinue
}
Image: profile.ps1
Image: The WFA >
PoSH > Modules folder
Image: The
WfaConfig.psm1 and WFAWrapper.psm1 files are worth a look to help your
understanding of how WFA and PowerShell works
Comments
Post a Comment