Created
September 25, 2016 00:11
-
-
Save lonniev/dbf81bfddce0c9e7fc9c57d7896447bd to your computer and use it in GitHub Desktop.
An Alternative construction of the TaskDefinition for Vagrant's 1.8.5 winrm communicator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param([String]$username, [String]$password, [String]$encoded_command, [String]$execution_time_limit) | |
# Try to get the Schedule.Service object. If it fails, we are probably | |
# on an older version of Windows. On old versions, we can just execute | |
# directly since priv. escalation isn't a thing. | |
$schedule = $null | |
Try { | |
$schedule = New-Object -ComObject "Schedule.Service" | |
} Catch [System.Management.Automation.PSArgumentException] { | |
powershell.exe -EncodedCommand $encoded_command | |
exit $LASTEXITCODE | |
} | |
$ProgressPreference = "SilentlyContinue" | |
$task_name = "WinRM_Elevated_Shell" | |
$out_file = "$env:TEMP\WinRM_Elevated_Shell.log" | |
remove-item -force -ErrorAction SilentlyContinue $out_file | |
$arguments = "/c powershell.exe -EncodedCommand $encoded_command > $out_file 2>&1" | |
$schedule.Connect() | |
$task = $schedule.NewTask(0) | |
$folder = $schedule.GetFolder("\") | |
$task.RegistrationInfo.Author = "$username" | |
$task.RegistrationInfo.Description = "Elevation Script for WinRM for Vagrant created without XML" | |
$task.Principal.id = "Author" | |
$task.Principal.UserId = "$username" | |
# $task.Principal.LogonType = 1 TASK_LOGON_PASSWORD (required at Task Registration, now) | |
$task.Principal.LogonType = 6 # TASK_LOGON_INTERACTIVE_TOKEN_OR_PASSWORD | |
$task.Principal.RunLevel = 1 # HighestAvailable | |
# now specify each Setting | |
$settings = $task.Settings | |
$settings.MultipleInstances = 3 # TASK_INSTANCES_STOP_EXISTING | |
$settings.DisallowStartIfOnBatteries = $false | |
$settings.StopIfGoingOnBatteries = $false | |
$settings.AllowHardTerminate = $true | |
$settings.StartWhenAvailable = $false | |
$settings.RunOnlyIfNetworkAvailable =$false | |
$settings.IdleSettings.StopOnIdleEnd = $false | |
$settings.IdleSettings.RestartOnIdle = $false | |
$settings.AllowDemandStart = $true | |
$settings.Enabled = $true | |
$settings.Hidden = $false | |
$settings.RunOnlyIfIdle = $false | |
$settings.WakeToRun = $false | |
$settings.ExecutionTimeLimit = $execution_time_limit | |
$settings.Priority = 4 | |
# specify the Action to execute when run | |
$action = $task.Actions.Create( 0 ) # ActionTypeExec | |
$action.Path = "cmd.exe" | |
$action.Arguments = $arguments | |
$folder.RegisterTaskDefinition( $task_name, $task, 6, $username, $password, 6) | Out-Null | |
$registered_task = $folder.GetTask("\$task_name") | |
"Beginning elevated WinRM task" | out-file $out_file | |
Try { | |
$registered_task.Run($null) | Out-Null | |
} | |
Catch { | |
$rtName = $registered_task.Name | |
"$rtName not Runnable." | out-file $out_file -append | |
} | |
$timeout = 10 | |
$sec = 0 | |
while ( (!($registered_task.state -eq 4)) -and ($sec -lt $timeout) ) { | |
Start-Sleep -s 1 | |
$sec++ | |
} | |
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 | |
} | |
$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 | |
exit $exit_code | |
param([String]$username, [String]$password, [String]$encoded_command, [String]$execution_time_limit) | |
# Try to get the Schedule.Service object. If it fails, we are probably | |
# on an older version of Windows. On old versions, we can just execute | |
# directly since priv. escalation isn't a thing. | |
$schedule = $null | |
Try { | |
$schedule = New-Object -ComObject "Schedule.Service" | |
} Catch [System.Management.Automation.PSArgumentException] { | |
powershell.exe -EncodedCommand $encoded_command | |
exit $LASTEXITCODE | |
} | |
$ProgressPreference = "SilentlyContinue" | |
$task_name = "WinRM_Elevated_Shell" | |
$out_file = "$env:TEMP\WinRM_Elevated_Shell.log" | |
remove-item -force -ErrorAction SilentlyContinue $out_file | |
$arguments = "/c powershell.exe -EncodedCommand $encoded_command > $out_file 2>&1" | |
$schedule.Connect() | |
$task = $schedule.NewTask(0) | |
$folder = $schedule.GetFolder("\") | |
$task.RegistrationInfo.Author = "$username" | |
$task.RegistrationInfo.Description = "Elevation Script for WinRM for Vagrant created without XML" | |
$task.Principal.id = "Author" | |
$task.Principal.UserId = "$username" | |
# $task.Principal.LogonType = 1 TASK_LOGON_PASSWORD (required at Task Registration, now) | |
$task.Principal.LogonType = 6 # TASK_LOGON_INTERACTIVE_TOKEN_OR_PASSWORD | |
$task.Principal.RunLevel = 1 # HighestAvailable | |
# now specify each Setting | |
$settings = $task.Settings | |
$settings.MultipleInstances = 3 # TASK_INSTANCES_STOP_EXISTING | |
$settings.DisallowStartIfOnBatteries = $false | |
$settings.StopIfGoingOnBatteries = $false | |
$settings.AllowHardTerminate = $true | |
$settings.StartWhenAvailable = $false | |
$settings.RunOnlyIfNetworkAvailable =$false | |
$settings.IdleSettings.StopOnIdleEnd = $false | |
$settings.IdleSettings.RestartOnIdle = $false | |
$settings.AllowDemandStart = $true | |
$settings.Enabled = $true | |
$settings.Hidden = $false | |
$settings.RunOnlyIfIdle = $false | |
$settings.WakeToRun = $false | |
$settings.ExecutionTimeLimit = $execution_time_limit | |
$settings.Priority = 4 | |
# specify the Action to execute when run | |
$action = $task.Actions.Create( 0 ) # ActionTypeExec | |
$action.Path = "cmd.exe" | |
$action.Arguments = $arguments | |
$folder.RegisterTaskDefinition( $task_name, $task, 6, $username, $password, 6) | Out-Null | |
$registered_task = $folder.GetTask("\$task_name") | |
"Beginning elevated WinRM task" | out-file $out_file | |
Try { | |
$registered_task.Run($null) | Out-Null | |
} | |
Catch { | |
$rtName = $registered_task.Name | |
"$rtName not Runnable." | out-file $out_file -append | |
} | |
$timeout = 10 | |
$sec = 0 | |
while ( (!($registered_task.state -eq 4)) -and ($sec -lt $timeout) ) { | |
Start-Sleep -s 1 | |
$sec++ | |
} | |
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 | |
} | |
$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 | |
exit $exit_code |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment