core/modules/monkeyjob/private/New-InitialSessionState.ps1
|
# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Function New-InitialSessionState{ <# .SYNOPSIS .DESCRIPTION .INPUTS .OUTPUTS .EXAMPLE .NOTES Author : Juan Garrido Twitter : @tr1ana File Name : New-InitialSessionState Version : 1.0 .LINK https://github.com/silverhack/monkey365 #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Scope="Function")] [CmdletBinding()] [OutputType([System.Management.Automation.Runspaces.InitialSessionState])] Param ( [Parameter(HelpMessage="variables to import into sessionState")] [Object]$ImportVariables, [Parameter(HelpMessage="modules to import into sessionState")] [Object]$ImportModules, [Parameter(HelpMessage="Functions to import from PS1 files into sessionState")] [Object]$ImportCommands, [Parameter(HelpMessage="Functions as StatementAst to import into sessionState")] [Object]$ImportCommandsAst, [Parameter(HelpMessage="Startup scripts (*ps1 files) to execute")] [System.Object[]]$StartUpScripts, [Parameter(HelpMessage="ApartmentState of the thread")] [ValidateSet("STA","MTA")] [String]$ApartmentState = "MTA", [Parameter(Mandatory=$False, HelpMessage='ThrowOnRunspaceOpenError')] [Switch]$ThrowOnRunspaceOpenError ) Begin{ try{ $sessionstate = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault() } catch{ $sessionstate = $null } } Process{ If($null -ne $sessionstate -and $sessionstate -is [System.Management.Automation.Runspaces.InitialSessionState]){ If($ImportVariables){ $all_scopes = [System.Management.Automation.ScopedItemOptions]::AllScope $allVars = [System.Collections.Generic.List[System.Management.Automation.Runspaces.SessionStateVariableEntry]]::new(); $all_vars = [System.Collections.ArrayList]::new() #Set a Hashset collection of existing variables $existing = [System.Collections.Generic.HashSet[string]]([System.StringComparer]::OrdinalIgnoreCase) #Populate hashset @($sessionState.Variables.Name).ForEach({[void]$existing.Add($_)}) If(([System.Collections.IDictionary]).IsAssignableFrom($ImportVariables.GetType())){ Foreach ($var in $ImportVariables.GetEnumerator()){ If($null -eq $var.Value){ Write-Verbose ($Script:messages.NullVariableMessage -f $var.Name) continue } Else{ If($existing.Add($var.Name)){ $_newVar = New-Object -TypeName System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList $var.Name, $var.Value, $null #Add var $sessionState.Variables.Add($_newVar) } } } } Else{ ForEach ($varname in $ImportVariables){ If ($MyInvocation.CommandOrigin -eq 'Runspace') { $localVar = Get-Variable $varname -ErrorAction Ignore | Where-Object { $_.Options -notmatch 'Constant' } If($null -ne $localVar){ [void]$all_vars.Add($localVar) } } ElseIf($null -ne $PSCmdlet.SessionState.PSVariable.Get($varname)){ $localVar = $PSCmdlet.SessionState.PSVariable.Get($varname) If($null -ne $localVar){ [void]$all_vars.Add($localVar) } } Else{ $localVar = Get-Variable -Name $varname -ErrorAction Ignore If($null -ne $localVar){ [void]$all_vars.Add($localVar) } } } If ($all_vars.Count -gt 0){ #Add vars into session state ForEach ($var in $all_vars){ $varToImport = [System.Management.Automation.Runspaces.SessionStateVariableEntry]::new($var.Name, ` $var.Value, ` $var.Description, ` $all_scopes) #Add var $sessionState.Variables.Add($varToImport) } } } } #Check if should import modules If($ImportModules){ If(([System.Collections.IDictionary]).IsAssignableFrom($ImportModules.GetType())){ $ImportModules = $ImportModules.Values } ForEach($module in $ImportModules){ $moduleToImport = Resolve-Path -Path $module -ErrorAction Ignore If($null -ne $moduleToImport){ Write-Verbose ($Script:messages.ImportingModuleMessage -f $module) $moduleToImport = $moduleToImport.Path.TrimEnd('\') If (Test-Path -Path $moduleToImport -PathType Container){ #folder containing one or more scripts/modules [void]$sessionstate.ImportPSModulesFromPath($moduleToImport); } Else{ #script, binary file, etc.. [void]$sessionstate.ImportPSModule($moduleToImport); } } Else{ #Check if file or module exists If (Test-Path -Path $module){ Write-Verbose ($Script:messages.ImportingModuleMessage -f $module) [void]$sessionstate.ImportPSModule($module); } Else{ Write-Warning ($Script:messages.ModuleNotExists -f $module) } } } } If($ImportCommands){ $CommandsToImport = $ImportCommands | Find-FunctionFromFile -FindAll $allcommands = [System.Collections.Generic.List[System.Management.Automation.Runspaces.SessionStateFunctionEntry]]::new(); $_commands = @($CommandsToImport).Where({$null -ne $_ -and $_ -is [System.Management.Automation.Language.FunctionDefinitionAst]}); ForEach($_command in $_commands.GetEnumerator()){ Write-Verbose ($Script:messages.ImportingFunctionMessage -f $_command.Name) $SessionStateFunction = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList $_command.Name, $_command.Body.GetScriptBlock() [void]$allcommands.Add($SessionStateFunction); } # Add all entries ForEach($cmd in $allcommands.GetEnumerator()){ $sessionstate.Commands.Add($cmd) } <# ForEach($fnc in @($CommandsToImport).Where({$null -ne $_})){ If($fnc -is [System.Management.Automation.Language.FunctionDefinitionAst]){ Write-Verbose ($Script:messages.ImportingFunctionMessage -f $fnc.Name) $SessionStateFunction = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList $fnc.Name, $fnc.Body.GetScriptBlock() #Create a SessionStateFunction $sessionstate.Commands.Add($SessionStateFunction) } } #> } If($ImportCommandsAst){ $allcommands = [System.Collections.Generic.List[System.Management.Automation.Runspaces.SessionStateFunctionEntry]]::new(); $_commands = @($ImportCommandsAst).Where({$null -ne $_ -and $_ -is [System.Management.Automation.Language.StatementAst]}); ForEach($_command in $_commands.GetEnumerator()){ Write-Verbose ($Script:messages.ImportingStatementAstMessage -f $_command.Name) $SessionStateFunction = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList $_command.Name, $_command.Body.GetScriptBlock() [void]$allcommands.Add($SessionStateFunction); } # Add all entries ForEach($cmd in $allcommands.GetEnumerator()){ $sessionstate.Commands.Add($cmd) } <# ForEach($fnc in @($ImportCommandsAst).Where({$null -ne $_})){ If($fnc -is [System.Management.Automation.Language.StatementAst]){ $SessionStateFunction = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList $fnc.Name, $fnc.Body.GetScriptBlock() Write-Verbose ($Script:messages.ImportingStatementAstMessage -f $fnc.Name) #Create a SessionStateFunction $sessionstate.Commands.Add($SessionStateFunction) } } #> } #Check if startup scripts If($StartUpScripts){ ForEach($scp in $StartUpScripts){ If([System.IO.File]::Exists($scp)){ [void]$sessionstate.StartupScripts.Add($scp) } Else{ Write-Warning ($Script:messages.FileNotExists -f $scp) continue } } } #Check for ThrowOnRunspaceOpenError flag If($ThrowOnRunspaceOpenError){ $sessionstate.ThrowOnRunspaceOpenError = $ThrowOnRunspaceOpenError } #Define ApartmentState $sessionstate.ApartmentState = [System.Threading.ApartmentState]::$ApartmentState } } End{ return $sessionstate } } |