SPE.psm1
$assemblies = @("\Libraries\Cognifide.PowerShell.dll", "\Libraries\Sitecore.Kernel.dll") foreach($assembly in $assemblies) { $path = Join-Path -Path $PSScriptRoot -ChildPath $assembly if(Test-Path -Path $path) { [System.Reflection.Assembly]::LoadFile($path) } } function Get-UsingVariables { param ([scriptblock]$ScriptBlock) if($ScriptBlock.ToString().IndexOf("`$using:", [System.StringComparison]::OrdinalIgnoreCase) -eq -1) { return } $ScriptBlock.Ast.FindAll({$args[0] -is [System.Management.Automation.Language.UsingExpressionAst]},$true) } function Get-UsingVariableValues { param ([System.Management.Automation.Language.UsingExpressionAst[]]$usingVar) $usingVar = $usingVar | Group SubExpression | ForEach {$_.Group | Select -First 1} ForEach ($var in $usingVar) { try { $value = $null $isRunspace = ($MyInvocation.CommandOrigin -eq [System.Management.Automation.CommandOrigin]::Runspace -or $MyInvocation.CommandOrigin -eq [System.Management.Automation.CommandOrigin]::Internal) $userpath = $Var.SubExpression.VariablePath.UserPath if ($isRunspace -and (Test-Path -Path "variable:\$($userpath)")) { Write-Verbose "Checking the Runspace for the variable $($userpath)." $value = Get-Variable -Name $userpath } if($value -eq $null -or [string]::IsNullOrEmpty($value.Value)) { Write-Verbose "Checking the SessionState for the variable $($userpath)." $value = ($PSCmdlet.SessionState.PSVariable.Get($userpath)) if ([string]::IsNullOrEmpty($value)) { throw 'No value!' } } [pscustomobject]@{ Name = $var.SubExpression.Extent.Text Value = $value.Value NewName = ('$__using_{0}' -f $var.SubExpression.VariablePath.UserPath) NewVarName = ('__using_{0}' -f $var.SubExpression.VariablePath.UserPath) } } catch { throw "The value of the using variable '$($var.SubExpression.Extent.Text)' cannot be retrieved because it has not been set in the local session." } } } function Convert-UsingScript { Param ( [scriptblock]$ScriptBlock ) $usingVariables = @(Get-UsingVariables -ScriptBlock $ScriptBlock) $list = New-Object 'System.Collections.Generic.List`1[System.Management.Automation.Language.VariableExpressionAst]' $params = New-Object System.Collections.ArrayList if ($script:Add_) { $params.Add('$_') | Out-Null } if ($usingVariables) { foreach ($ast in $usingVariables) { $list.Add($ast.SubExpression) | Out-Null } $usingVariableData = @(Get-UsingVariableValues $usingVariables) $params.AddRange(@($usingVariableData.NewName | Select -Unique)) | Out-Null } $newParams = $params -join ', ' $tuple=[Tuple]::Create($list, $newParams) $bindingFlags = [Reflection.BindingFlags]"Default,NonPublic,Instance" $getWithInputHandlingForInvokeCommandImpl = ($scriptBlock.ast.gettype().GetMethod('GetWithInputHandlingForInvokeCommandImpl',$bindingFlags)) $stringScriptBlock = $getWithInputHandlingForInvokeCommandImpl.Invoke($scriptBlock.ast,@($tuple)) if ([scriptblock]::Create($stringScriptBlock).Ast.endblock[0].statements.extent.text.startswith('$input |')) { $stringScriptBlock = $stringScriptBlock -replace '\$Input \|' } if (-NOT $scriptBlock.Ast.ParamBlock) { $stringScriptBlock = "param($($newParams))`n$($stringScriptBlock)" [scriptblock]::Create($stringScriptBlock) } else { [scriptblock]::Create($stringScriptBlock) } } function New-UsingBlock { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [AllowEmptyString()] [AllowEmptyCollection()] [AllowNull()] [Object] $InputObject, [Parameter(Mandatory = $true)] [scriptblock] $ScriptBlock ) try { . $ScriptBlock } finally { if ($null -ne $InputObject -and $InputObject -is [System.IDisposable]) { $InputObject.Dispose() } } } |