Bypassing Restricted Execution Policy in Code or in Script

by oising 10. February 2012 23:34

Many businesses are averse to moving away from a restricted execution policy because they don't really understand it. As Microsoft will tell you, It's not a security boundary - it's just an extra hoop to jump through so you don't shoot yourself in the foot by running something you shouldn’t. If you want to run ps1 scripts in your own application, simply host your own Runspace and use the base authorization manager which pays no heed to system execution policy, even if it’s controlled by group policy and immune to powershell –bypass and set-executiopolicy:

Bypassing in Code

InitialSessionState initial = InitialSessionState.CreateDefault(); 
 
// Replace PSAuthorizationManager with a null manager
// which ignores execution policy 
initial.AuthorizationManager = new 
      System.Management.Automation.AuthorizationManager("MyShellId"); 
 
// Extract psm1 from resource, save locally 
// ... 
 
// load my extracted module with my commands 
initial.ImportPSModule(new[] { <path_to_psm1> }); 
 
// open runspace 
Runspace runspace = RunspaceFactory.CreateRunspace(initial); 
runspace.Open(); 
 
RunspaceInvoke invoker = new RunspaceInvoke(runspace); 
 
// execute a command from my module 
Collection<PSObject> results = invoker.Invoke("my-command"); 
 
// or run a ps1 script     
Collection<PSObject> results = invoker.Invoke(@"c:\program files\myapp\my.ps1");

By using this null authorization manager, execution policy is completed ignored. Remember - this is not some "hack" because execution policy is something for protecting users against themselves. It's not for protecting against malicious third parties, like some kind of script firewall. Whatever could be put in a script, could be run by hand in a dozen different ways using invoke-expression, and even file based scripts can be executed this way: invoke-expression (get-content .\foo.ps1).

Bypassing in Script

Now this is a little more hackish because it involves manipulating powershell.exe internals at runtime. This is a useful one-liner (if you can memorise it) when you find yourself in one of those clients who has GPO controlled execution policy. It’s pushing it for a one-liner, I know, but hey:

function Disable-ExecutionPolicy {
    ($ctx = $executioncontext.gettype().getfield(
        "_context","nonpublic,instance").getvalue(
            $executioncontext)).gettype().getfield(
                "_authorizationManager","nonpublic,instance").setvalue(
        $ctx, (new-object System.Management.Automation.AuthorizationManager
                  "Microsoft.PowerShell"))
}

This function will swap out the powershell host’s AuthorizationManager implementation (PSAuthorizationManager) with the null, policy-ignoring version. Execution policy will be effectively unrestricted, regardless of enterprise, machine or user level attempts to set it to restricted. This is an in-memory bypass only – when powershell.exe is closed and restarted, it’s back to business (or lack thereof.)

Have fun!

Tags:

.NET | Developer | PowerShell 2.0 | PowerShell 3.0 | PowerShell | Reflection

PowerShell Script Provider

by oising 26. July 2010 21:33

Write your own PowerShell provider using only script, no C# required. Module definition is provided by a Windows PowerShell 2.0 Module, which may be pure script, binary or a mix of both.

Debugging is as easy as any ordinary ps1 script file:

image

All functions in backing module reflect the same signature as those found on MSDN. This means that you go to MSDN documentation on providers to learn about how to write the corresponding script.

Current Release PSProvider 0.4

Samples and Templates

Roadmap

0.1
  • ContainerCmdletProvider support through "ModuleBoundProvider" provider
  • Demo provider included navigating a Hashtable
  • Can be debugged in the debugger of your choice: console, ISE, PowerGUI.
0.2
  • NavigationCmdletProvider support
  • Providers rename to ContainerScriptProvider and TreeScriptProvider
  • Container Sample & Tree Template modules
  • Supports: Clear-Item, Copy-Item, Get-Item, Invoke-Item, Move-Item, New-Item, Remove-Item, Rename-Item, Set-Item
0.3
  • IContentCmdletProvider support
  • New Commands: New-ContentReader, New-ContentWriter implement IContentReader, IContentWriter
  • Adds support for: Add-Content, Clear-Content, Get-Content, Set-Content
0.4 (Current Release)
  • IPropertyCmdletProvider support
  • Adds support for: Clear-ItemProperty, Copy-ItemProperty, Get-ItemProperty, Move-ItemProperty, New-ItemProperty, Remove-ItemProperty, Rename-ItemProperty, Set-ItemProperty
0.5
  • Dynamic Parameter support
0.6
  • Security Interfaces
  • Adds support for: Get-ACL, Set-ACL

http://psprovider.codeplex.com/

Tags:

.NET | Cmdlets | CodePlex | Developer | Modules | PowerShell | PowerShell 2.0 | Providers

PowerShell 2.0 – PSCX Labs: Invoke-Reflector

by oising 5. May 2010 21:05

This is a lot of fun if you spend a lot of time tinkering around with APIs in PowerShell. This function (included in the upcoming PSCX 2.0, alias: refl) will let you open Lutz Roeder’s Reflector for any Type or Cmdlet. Reflector will automatically load the correct Assembly and will highlight the relevant Type, without you having to do diddley-squat. Examples and help will display with -?

function Invoke-Reflector {
<#
    .SYNOPSIS
        Quickly load Reflector, with the specified Type or Command selected.
    .DESCRIPTION
        Quickly load Reflector, with the specified Type or Command selected. The function will also
        ensure that Reflector has the Type or Command's containing Assembly loaded.
    .EXAMPLE
        # Opens System.String in Reflector. Will load its Assembly into Reflector if required.
        ps> [string] | invoke-reflector
    .EXAMPLE
        # Opens GetChildItemCommand in Reflector. Will load its Assembly into Reflector if required.
        ps> gcm ls | invoke-reflector
    .EXAMPLE
        # Opens GetChildItemCommand in Reflector. Will load its Assembly into Reflector if required.
        ps> invoke-reflector dir
    .PARAMETER CommandName
        Accepts name of command. Does not accept pipeline input.
    .PARAMETER CommandInfo
        Accepts output from Get-Command (gcm). Accepts pipeline input.
    .PARAMETER Type
        Accepts a System.Type (System.RuntimeType). Accepts pipeline input.
    .PARAMETER ReflectorPath
        Optional. Defaults to Reflector.exe's location if it is found in your $ENV:PATH. If not found, you must specify.
    .INPUTS
        [System.Type]
        [System.Management.Automation.CommandInfo]
    .OUTPUTS
        None
#>
     [cmdletbinding(defaultparametersetname="name")]
     param(
         [parameter(
            parametersetname="name",
            position=0,
            mandatory=$true
         )]
         [validatenotnullorempty()]
         [string]$CommandName,

         [parameter(
            parametersetname="command",
            position=0,
            valuefrompipeline=$true,
            mandatory=$true
         )]
         [validatenotnull()]
         [management.automation.commandinfo]$CommandInfo,

         [parameter(
            parametersetname="type",
            position=0,
            valuefrompipeline=$true,
            mandatory=$true
         )]
         [validatenotnull()]
         [type]$Type,

         [parameter(
            position=1
         )]
         [validatenotnullorempty()]
         [string]$ReflectorPath = $((gcm reflector.exe -ea 0).definition)
     )

        # no process block; i only want
        # a single reflector instance

        if ($ReflectorPath -and (test-path $reflectorpath)) {

            $typeName = $null
            $assemblyLocation = $null

            switch ($pscmdlet.parametersetname) {

                 { "name","command" -contains $_ } {

                    if ($CommandName) {
                        $CommandInfo = gcm $CommandName -ea 0
                    } else {
                        $CommandName = $CommandInfo.Name
                    }

                    if ($CommandInfo -is [management.automation.aliasinfo]) {

                        # expand aliases
                        while ($CommandInfo.CommandType -eq "Alias") {
                            $CommandInfo = gcm $CommandInfo.Definition
                        }
                    }

                    # can only reflect cmdlets, obviously.
                    if ($CommandInfo.CommandType -eq "Cmdlet") {

                        $typeName = $commandinfo.implementingtype.fullname
                        $assemblyLocation = $commandinfo.implementingtype.assembly.location

                    } elseif ($CommandInfo) {
                        write-warning "$CommandInfo is not a Cmdlet."
                    } else {
                        write-warning "Cmdlet $CommandName does not exist in current scope. Have you loaded its containing module or snap-in?"
                    }
                }

                "type" {
                    $typeName = $type.fullname
                    $assemblyLocation = $type.assembly.location
                }
            } # end switch


            if ($typeName -and $assemblyLocation) {
                & $reflectorPath /select:$typeName $assemblyLocation
            }

        } else {
            write-warning "Unable to find Reflector.exe. Please specify full path via -ReflectorPath."
        }
}

Have fun!

Tags:

.NET | Cmdlets | Developer | Functions | Monad | PowerShell | PowerShell 2.0 | PSCX

PowerShell 2.0 – Developer Essentials #1 – Initializing a Runspace with a Module

by oising 3. May 2010 16:54

These days I'm incredibly busy both in my professional and private life, so I’ve not had a lot of time to construct the usual meaty posts I like to write. Instead I figured I could write a series of short – very short – posts centered around the little tricks that you would need to be an efficient developer when targeting PowerShell. Here's the first tip: how to create a Runspace and have one or more Module(s) preloaded. The RunspaceInvoke class is a handy wrapper that will do most of the plumbing for you if you just want to run scripts or commands. If you want to manually construct your own Pipeline instances then you must work with the Runspace class directly.

    InitialSessionState initial = InitialSessionState.CreateDefault();
    initialSession.ImportPSModule(new[] { modulePathOrModuleName1, ... });
    Runspace runspace = RunspaceFactory.CreateRunspace(initial);
    runspace.Open();
    RunspaceInvoke invoker = new RunspaceInvoke(runspace);
    Collection<PSObject> results = invoker.Invoke("...");

Have fun!

Tags:

.NET | Cmdlets | Developer | Modules | Monad | PowerShell | PowerShell 2.0

About the author

Oisin Grehan lives in Montreal, Canada and builds all sorts of crap for all sorts of people.

Month List

Page List