Taliesin Sisson

My feedback

  1. 231 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    10 comments  ·  General  ·  Flag idea as inappropriate…  ·  Admin →
    Taliesin Sisson commented  · 

    It is possible to do this, by using scheduled tasks. This is how Vagrant and Packer do it:

    $command = @"
    `$ErrorActionPreference="Stop"
    whoami
    Write-host 'hello'
    "@

    function SlurpOutput($out_file, $cur_line) {
    if (Test-Path $out_file) {
    get-content $out_file | select -skip $cur_line | ForEach {
    $cur_line += 1
    Write-Host "$_"
    }
    }
    return $cur_line
    }

    function RunAsScheduledTask([String]$username, [String]$password, [String]$encoded_command) {
    $task_name = "WinRM_Elevated_Shell_Octopus"
    $out_file = "$env:SystemRoot\Temp\WinRM_Elevated_Shell_Otopus.log"

    if (Test-Path $out_file) {
    del $out_file
    }

    $task_xml = @'
    <?xml version="1.0" encoding="UTF-16"?>
    <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
    <Principals>
    <Principal id="Author">
    <UserId>{username}</UserId>
    <LogonType>Password</LogonType>
    <RunLevel>HighestAvailable</RunLevel>
    </Principal>
    </Principals>
    <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
    <StopOnIdleEnd>false</StopOnIdleEnd>
    <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT2H</ExecutionTimeLimit>
    <Priority>4</Priority>
    </Settings>
    <Actions Context="Author">
    <Exec>
    <Command>cmd</Command>
    <Arguments>{arguments}</Arguments>
    </Exec>
    </Actions>
    </Task>
    '@

    $arguments = "/c powershell.exe -NonInteractive -EncodedCommand $encoded_command &gt; $out_file 2&gt;&amp;1"

    $task_xml = $task_xml.Replace("{arguments}", $arguments)
    $task_xml = $task_xml.Replace("{username}", $username)

    $schedule = New-Object -ComObject "Schedule.Service"
    $schedule.Connect()
    $task = $schedule.NewTask($null)
    $task.XmlText = $task_xml

    $folder = $schedule.GetFolder("\")
    $folder.RegisterTaskDefinition($task_name, $task, 6, $username, $password, 1, $null) | Out-Null

    $registered_task = $folder.GetTask("\$task_name")
    $registered_task.Run($null) | Out-Null

    $timeout = 10
    $sec = 0
    while ( (!($registered_task.state -eq 4)) -and ($sec -lt $timeout) ) {
    Start-Sleep -s 1
    $sec++
    }

    $cur_line = 0
    do {
    Start-Sleep -m 100
    $cur_line = SlurpOutput $out_file $cur_line
    } while (!($registered_task.state -eq 3))

    $exit_code = $registered_task.LastTaskResult
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($schedule) | Out-Null

    return $exit_code
    }

    $bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
    $encodedCommand =[Convert]::ToBase64String($bytes)

    $exitCode = RunAsScheduledTask -username $ServiceBusServiceUsername -password $ServiceBusServicePassword -encoded_command $encodedCommand

    exit $exitCode

Feedback and Knowledge Base