PoshExec.ps1
function Start-RemoteProcess { [CmdletBinding()] param( [Parameter()] $ComputerName, [Parameter(Mandatory)] [System.Management.Automation.Credential()] $Credential=[System.Management.Automation.PSCredential]::Empty, [Parameter()] $FilePath, [Parameter()] [Switch]$Interact, [Parameter()] [Switch]$Cleanup ) $Service = Get-Service -ComputerName $ComputerName -Name "PoshExecSvr" -ErrorAction SilentlyContinue $drive = Get-PSDrive -Name "$ComputerName Admin" -ErrorAction SilentlyContinue if ($drive -eq $null) { Write-Verbose "Mapping admin share drive." New-PSDrive -Name "$ComputerName Admin" -Root "\\$ComputerName\Admin`$" -Credential $Credential -PSProvider FileSystem | Out-Null } if ($Service -eq $null) { $Binary = Join-Path ([io.path]::GetTempPath()) "PoshExecSvr.exe" $ScriptDirectory = $MyInvocation.MyCommand.Module.ModuleBase Write-Verbose "Compiling PoshExecSvr service." Add-Type -OutputType ConsoleApplication -OutputAssembly $Binary -ReferencedAssemblies "System.Data","System.ServiceProcess","System.Xml" -Path (Join-Path $ScriptDirectory "PoshExec.cs") Write-Verbose "Copying service to remote machine [$ComputerName]." Copy-Item $Binary "$ComputerName Admin:\PoshExecSvr.exe" Write-Verbose "Creating service using service control manager." $SCArgs = @("\\$ComputerName","create","PoshExecSvr","binpath= C:\windows\PoshExecSvr.exe") Start-Process -FilePath "C:\windows\system32\sc.exe" -ArgumentList $SCArgs -Credential $Credential -Wait -WindowStyle Hidden } Write-Verbose "Validating service is running." $Service = Get-Service -ComputerName $ComputerName -Name "PoshExecSvr" -ErrorAction SilentlyContinue #Sometimes the service isn't quite installed, even if we wait for sc.exe to exit if ($Service -eq $null -and $Services.Status -ne 'Running') { Start-Sleep -Milliseconds 500 Get-Service -ComputerName $ComputerName -Name "PoshExecSvr" | Start-Service } elseif ($Services.Status -ne 'Running') { Write-Verbose "Starting service." $service | Start-Service } Add-Type " namespace PoshExecSvr { [System.Serializable] public class StartInfo { public string CommandLine; public bool Interact; } } " $StartInfo = New-Object PoshExecSvr.StartInfo $StartInfo.CommandLine = $FilePath $StartInfo.Interact = $Interact $Stream = New-Object System.IO.MemoryStream $Serializer = New-Object System.Xml.Serialization.XmlSerializer -ArgumentList ([PoshExecSvr.StartInfo]) $Serializer.Serialize($stream, $startInfo) $stream.position = 0 $sr = New-Object -TypeName System.IO.StreamReader -ArgumentList $stream $xml = $sr.ReadToEnd() Write-Verbose "Sending start up info to service." Send-NamedPipeMessage -PipeName "PoshExecSvrPipe" -ComputerName $ComputerName -Message $XML if ($Cleanup) { Write-Verbose "Cleaning up service." $Service | Stop-Service Start-Process -FilePath "C:\windows\system32\sc.exe" -ArgumentList "\\$ComputerName","delete","PoshExecSvr" -Credential $Credential -Wait Remove-Item "$ComputerName Admin:\PoshExecSvr.exe" Remove-PSDrive -Name "$ComputerName Admin" } } |