Skip to content

Instantly share code, notes, and snippets.

@lonniev
Created September 25, 2016 00:11
Show Gist options
  • Save lonniev/dbf81bfddce0c9e7fc9c57d7896447bd to your computer and use it in GitHub Desktop.
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
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