Neptune443

Invoke-AsSystem

Nov 10th, 2014
366
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Function Invoke-AsSystem {
  2.     #
  3.     # Invoke-AsSystem is a quick hack to run a PS ScriptBlock as the System account
  4.     # It is possible to pass and retrieve object through the pipeline, though objects
  5.     # are passed as serialized objects using export/clixml.
  6.     #  
  7.  
  8.     param(
  9.         #[Parameter(Mandatory=$true)]
  10.         [scriptblock]$Process={ls},
  11.         [scriptblock]$Begin={},
  12.         [scriptblock]$End={},
  13.         [int]$Depth = 4
  14.     )
  15.     begin {
  16.         Function Test-Elevated {
  17.             $wid=[System.Security.Principal.WindowsIdentity]::GetCurrent()
  18.             $prp=new-object System.Security.Principal.WindowsPrincipal($wid)
  19.             $adm=[System.Security.Principal.WindowsBuiltInRole]::Administrator
  20.             $prp.IsInRole($adm)
  21.         }
  22.     $code = @"
  23. using System;
  24. using System.ServiceProcess;
  25. namespace CosmosKey.Powershell.InvokeAsSystemSvc
  26. {
  27.    class TempPowershellService : ServiceBase
  28.    {
  29.        static void Main()
  30.        {
  31.            ServiceBase.Run(new ServiceBase[] { new TempPowershellService() });
  32.        }
  33.        protected override void OnStart(string[] args)
  34.        {
  35.            string[] clArgs = Environment.GetCommandLineArgs();
  36.            try
  37.            {
  38.                string argString = String.Format(
  39.                    "-command .{{import-clixml '{0}' | .'{1}' | export-clixml -Path '{2}' -Depth {3}}}",
  40.                    clArgs[1],
  41.                    clArgs[2],
  42.                    clArgs[3],
  43.                    clArgs[5]);
  44.                System.Diagnostics.Process.Start("powershell", argString).WaitForExit();
  45.                System.IO.File.AppendAllText(clArgs[4], "success");
  46.            }
  47.            catch (Exception e)
  48.            {
  49.                System.IO.File.AppendAllText(clArgs[4], "fail\r\n" + e.Message);
  50.            }
  51.        }
  52.        protected override void OnStop()
  53.        {
  54.        }
  55.    }
  56. }
  57. "@
  58.         if( -not (Test-Elevated)) {
  59.             throw "Process is not running as an eleveated process. Please run as elevated."
  60.         }
  61.         [void][System.Reflection.Assembly]::LoadWithPartialName("System.ServiceProcess")  
  62.         $serviceNamePrefix = "MyTempPowershellSvc"
  63.         $timeStamp = get-date -Format yyyyMMdd-HHmmss
  64.         $serviceName = "{0}-{1}" -f $serviceNamePrefix,$timeStamp
  65.         $tempPSexe   = "{0}.exe" -f $serviceName,$timeStamp
  66.         $tempPSout   = "{0}.out" -f $serviceName,$timeStamp
  67.         $tempPSin    = "{0}.in"  -f $serviceName,$timeStamp
  68.         $tempPSscr   = "{0}.ps1" -f $serviceName,$timeStamp
  69.         $tempPScomplete   = "{0}.end" -f $serviceName,$timeStamp
  70.         $servicePath = Join-Path $env:temp $tempPSexe
  71.         $outPath     = Join-Path $env:temp $tempPSout
  72.         $inPath      = Join-Path $env:temp $tempPSin
  73.         $scrPath     = Join-Path $env:temp $tempPSscr
  74.         $completePath     = Join-Path $env:temp $tempPScomplete
  75.         $serviceImagePath = "`"{0}`" `"{1}`" `"{2}`" `"{3}`" `"{4}`" {5}" -f $servicePath,$inPath,$scrPath,$outPath,$completePath,$depth
  76.         Add-Type $code -ReferencedAssemblies "System.ServiceProcess" -OutputAssembly $servicePath -OutputType WindowsApplication | Out-Null
  77.         $objectsFromPipeline = new-object Collections.ArrayList
  78.         $script = "BEGIN {{{0}}}`nPROCESS {{{1}}}`nEND {{{2}}}" -f $Begin.ToString(),$Process.ToString(),$End.ToString()
  79.         $script.ToString() | Out-File -FilePath $scrPath -Force    
  80.     }
  81.  
  82.     process {
  83.         [void]$objectsFromPipeline.Add($_)
  84.     }
  85.  
  86.     end
  87.     {
  88.         $objectsFromPipeline | Export-Clixml -Path $inPath -Depth $Depth
  89.         New-Service -Name $serviceName -BinaryPathName $serviceImagePath -DisplayName $serviceName -Description $serviceName -StartupType Manual | out-null
  90.         $service = Get-Service $serviceName
  91.         $service.Start() | out-null
  92.         while ( -not (test-path $completePath)) {
  93.             start-sleep -Milliseconds 100
  94.         }
  95.         $service.Stop() | Out-Null
  96.         do {
  97.             $service = Get-Service $serviceName
  98.         } while($service.Status -ne "Stopped")
  99.         (Get-WmiObject win32_service -Filter "name='$serviceName'").delete() | out-null
  100.         Import-Clixml -Path $outPath
  101.         Remove-Item $servicePath -Force | out-null
  102.         Remove-Item $inPath      -Force | out-null
  103.         Remove-Item $outPath     -Force | out-null
  104.         Remove-Item $scrPath     -Force | out-null
  105.         Remove-Item $completePath     -Force | out-null
  106.     }
  107. }
Advertisement
Add Comment
Please, Sign In to add comment