Disclaimer: I have no SharePoint experience; if better solutions exist, do tell us.
[Microsoft.SharePoint.SPSecurity]::RunWithElevatedPrivileges()
has only one parameter, namely a delegate
instance to which no parameters are passed.
Thus, there is also no way to pass parameters to a PowerShell script block acting as such a delegate.
A script block that runs in the same PowerShell runspace (which implies the same thread) would implicitly have access to the caller's variables (due to PowerShell's dynamic scoping), but this seems not to be the case in your scenario.
A - limited and cumbersome - workaround is to construct your script block as a string, using string interpolation to "bake in" (embed in the source code) the values you want to pass as arguments.
The major limitation is:
- It only works for values of .NET data types that have literal source-code representations (and the embedded values are invariably copies of the original values).
This isn't much better than hard-coding values directly in the script block, but it does allow you to embed values not known at design time, and it amounts to a more maintainable solution.
The following is a minimal example that demonstrates the technique, using [scriptblock]::Create()
with an expandable (interpolating) here-string:
# A "parameter" (value) that you want to embed in the script block.
$myParam = 'Hello, world.'
# Create the script block's source code *as a string*, allowing you to
# use string interpolation.
$scriptBlockSourceCode = @"
# Use string interpolation to embed the value of $myParam
# Note: All $ characters to be preserved as part of the resulting
# code must be escaped as `$
`$myParam = '$myParam'
# Demonstrate that the value was successfully embedded.
Write-Verbose -Verbose ('The value of `$myParam is: ' + `$myParam)
"@
# Construct the script block from the source codde:
$scriptBlock = [scriptblock]::Create($scriptBlockSourceCode)
# For demo purposes, use a dummy call that involves a delegate in lieu
# of `[Microsoft.SharePoint.SPSecurity]::RunWithElevatedPrivileges()`,
# just to demonstrate that the value was correctly embedded.
[Array]::Find(
@(1),
[Predicate[object]] $scriptBlock
)
Note:
Reference variables whose values you want to embed by name (e.g., $myParam
); if you need to embed the value of an expression, enclose the reference in $(...)
(e.g., $($myParam.SomeProperty)
) - for a comprehensive overview of PowerShell's string interpolation, see this answer.
All $
characters that must be retained as such as part of the resulting source code must be escaped as `$
to prevent up-front expansion.
You need to ensure that expanded value works syntactically in the resulting source code, which notably means using embedded quoting (e.g., '$myParam'
) for embedded string values; if the value to embed contains quoting characters of the same type itself, you'll have to escape them (''
inside '...'
, `"
inside "..."
).