winrm-elevated 1.1.1 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4eafa3868086d590ce41b1b34631f82a2830d62ce635423cc17a7137ee82fe1
4
- data.tar.gz: 9e673bfbbbf91f8c3595b4ad2680d61bc12fe423bf2ff65c0a47196459fd9a12
3
+ metadata.gz: ee0adbdb22c257558248a863ab41505ef63bbe664150084be3cd57ecc56eef3e
4
+ data.tar.gz: d3442d4883f6617827977d6c2538f8d4961a1bf45de3e45be4c249e34ec548c3
5
5
  SHA512:
6
- metadata.gz: 15871834756bd792d2df264a426d8f3c4aa76cb083a279beeabccf8ffe2693413910ac59447dba6639201904bd5cd03e8b2ce4adb9263a27aab9a20b84bab56e
7
- data.tar.gz: 7648a7e4337a7b7f89e082725a96e1fe7764e5923053b18b4cb13b9eb62f378f1fd9b8db147c84b122e41b26a1ab988940c5cef567a26fbbfc054890170d9566
6
+ metadata.gz: 439dfd36cc9777886088dccb8172885844f319f3e808fb951b2eac31e115367e500f97b9d6fc2d0006588a7c1a8bedbb034d8af1678bc6d39d10647c6db2a958
7
+ data.tar.gz: 63935500fcb295b1359c2222cb1860788fbb2f7859c2f303c8928b61b478197c72e4fa2163070873e333e45d822a7164ea365947cdb5b7c3a6ca117ff20bdbc5
@@ -13,5 +13,5 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require 'winrm'
16
+ require 'winrm' unless defined?(WinRM::Connection)
17
17
  require_relative 'winrm/shells/elevated'
@@ -16,7 +16,7 @@ if($interactive -eq 'true') {
16
16
  $logon_type_xml = "<LogonType>InteractiveTokenOrPassword</LogonType>"
17
17
  }
18
18
 
19
- $task_name = "WinRM_Elevated_Shell"
19
+ $task_name = "WinRM_Elevated_Shell_" + [guid]::NewGuid()
20
20
  $out_file = [System.IO.Path]::GetTempFileName()
21
21
  $err_file = [System.IO.Path]::GetTempFileName()
22
22
 
@@ -64,44 +64,65 @@ $task_xml = $task_xml.Replace("{arguments}", $arguments)
64
64
  $task_xml = $task_xml.Replace("{username}", $username)
65
65
  $task_xml = $task_xml.Replace("{logon_type}", $logon_type_xml)
66
66
 
67
- $schedule = New-Object -ComObject "Schedule.Service"
68
- $schedule.Connect()
69
- $task = $schedule.NewTask($null)
70
- $task.XmlText = $task_xml
71
- $folder = $schedule.GetFolder("\")
72
- $folder.RegisterTaskDefinition($task_name, $task, 6, $username, $pass_to_use, $logon_type, $null) | Out-Null
67
+ try {
68
+ $schedule = New-Object -ComObject "Schedule.Service"
69
+ $schedule.Connect()
70
+ $task = $schedule.NewTask($null)
71
+ $task.XmlText = $task_xml
72
+ $folder = $schedule.GetFolder("\")
73
+ $folder.RegisterTaskDefinition($task_name, $task, 6, $username, $pass_to_use, $logon_type, $null) | Out-Null
73
74
 
74
- $registered_task = $folder.GetTask("\$task_name")
75
- $registered_task.Run($null) | Out-Null
75
+ $registered_task = $folder.GetTask("\$task_name")
76
+ $registered_task.Run($null) | Out-Null
76
77
 
77
- $timeout = 10
78
- $sec = 0
79
- while ( (!($registered_task.state -eq 4)) -and ($sec -lt $timeout) ) {
80
- Start-Sleep -s 1
81
- $sec++
78
+ $timeout = 10
79
+ $sec = 0
80
+ while ( (!($registered_task.state -eq 4)) -and ($sec -lt $timeout) ) {
81
+ Start-Sleep -s 1
82
+ $sec++
83
+ }
84
+ } catch {
85
+ Write-Error -ErrorRecord $PSItem
86
+ exit $PSItem.Exception.HResult
82
87
  }
83
88
 
84
89
  function SlurpOutput($file, $cur_line, $out_type) {
85
90
  if (Test-Path $file) {
86
- get-content $file | select -skip $cur_line | ForEach {
87
- $cur_line += 1
88
- if ($out_type -eq 'err') {
89
- $host.ui.WriteErrorLine("$_")
90
- } else {
91
- $host.ui.WriteLine("$_")
91
+ $fs = New-Object -TypeName System.IO.FileStream -ArgumentList @(
92
+ $file,
93
+ [system.io.filemode]::Open,
94
+ [System.io.FileAccess]::Read,
95
+ [System.IO.FileShare]::ReadWrite
96
+ )
97
+ try {
98
+ $enc = [System.Text.Encoding]::GetEncoding($Host.CurrentCulture.TextInfo.OEMCodePage)
99
+ $bytes = [System.Byte[]]::CreateInstance([System.Byte], $fs.Length)
100
+ if ($fs.Read($bytes, 0, $fs.Length) -gt 0) {
101
+ $text = $enc.GetString($bytes)
102
+ $text.TrimEnd("`n").TrimEnd("`r").Split(@("`r`n", "`n"), [StringSplitOptions]::None) | Select-Object -skip $cur_line | ForEach-Object {
103
+ $cur_line += 1
104
+ if ($out_type -eq 'err') {
105
+ $host.ui.WriteErrorLine("$_")
106
+ } else {
107
+ $host.ui.WriteLine("$_")
108
+ }
109
+ }
92
110
  }
93
111
  }
112
+ finally { $fs.Close() }
94
113
  }
95
114
  return $cur_line
96
115
  }
97
116
 
98
117
  $err_cur_line = 0
99
118
  $out_cur_line = 0
119
+ $timeout = <%= execution_timeout %>
120
+ $startDate = Get-Date
100
121
  do {
101
122
  Start-Sleep -m 100
102
123
  $out_cur_line = SlurpOutput $out_file $out_cur_line 'out'
103
124
  $err_cur_line = SlurpOutput $err_file $err_cur_line 'err'
104
- } while (!($registered_task.state -eq 3))
125
+ } while( (!($registered_task.state -eq 3)) -and ($startDate.AddSeconds($timeout) -gt (Get-Date)) )
105
126
 
106
127
  # We'll make a best effort to clean these files
107
128
  # But a reboot could possibly end the task while the process
@@ -111,6 +132,19 @@ try { Remove-Item $err_file -ErrorAction Stop } catch {}
111
132
  try { Remove-Item $script_file -ErrorAction Stop } catch {}
112
133
 
113
134
  $exit_code = $registered_task.LastTaskResult
135
+
136
+ try {
137
+ # Clean current task
138
+ $folder.DeleteTask($task_name, 0)
139
+ # Clean old tasks if required
140
+ $old_tasks_filter_date = [datetime]::Now.AddSeconds(<%= -1 * execution_timeout %>)
141
+ $old_tasks_to_kill = $folder.GetTasks(0) | Select Name,LastRunTime | Where-Object {
142
+ ($_.Name -like "WinRM_Elevated_Shell*") -and ($_.LastRunTime -le $old_tasks_filter_date) -and ($_.Name -ne $task_name)
143
+ }
144
+ $old_tasks_to_kill | ForEach-Object { try { $folder.DeleteTask($_.Name, 0) } catch {} }
145
+ }
146
+ catch {}
147
+
114
148
  [System.Runtime.Interopservices.Marshal]::ReleaseComObject($schedule) | Out-Null
115
149
 
116
150
  exit $exit_code
@@ -13,10 +13,11 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require 'erubis'
17
- require 'winrm'
16
+ require 'erubi'
17
+ require 'winrm' unless defined?(WinRM::Connection)
18
18
  require 'winrm-fs'
19
- require 'securerandom'
19
+ require 'securerandom' unless defined?(SecureRandom)
20
+ require 'stringio'
20
21
 
21
22
  module WinRM
22
23
  module Shells
@@ -33,6 +34,7 @@ module WinRM
33
34
  @interactive_logon = false
34
35
  @shell = Powershell.new(connection_opts, transport, logger)
35
36
  @winrm_file_transporter = WinRM::FS::Core::FileTransporter.new(@shell)
37
+ @execution_timeout = 86_400
36
38
  end
37
39
 
38
40
  # @return [String] The admin user name to execute the scheduled task as
@@ -44,6 +46,9 @@ module WinRM
44
46
  # @return [Bool] Using an interactive logon
45
47
  attr_accessor :interactive_logon
46
48
 
49
+ # @return [Integer] Timeout for the task to be executed
50
+ attr_accessor :execution_timeout
51
+
47
52
  # Run a command or PowerShell script elevated without any of the
48
53
  # restrictions that WinRM puts in place.
49
54
  #
@@ -68,35 +73,30 @@ module WinRM
68
73
 
69
74
  def upload_elevated_shell_script(script_text)
70
75
  elevated_shell_path = 'c:/windows/temp/winrm-elevated-shell-' + SecureRandom.uuid + '.ps1'
71
- with_temp_file(script_text) do |temp_file|
72
- @winrm_file_transporter.upload(temp_file, elevated_shell_path)
73
- end
76
+ # Prepend the content of the file with an UTF-8 BOM for Windows to read it as such instead of the default
77
+ # Windows-XXXX encoding, and convert script_text accordingly if needed.
78
+ script_text_with_exit = "\uFEFF#{script_text.encode(Encoding::UTF_8)}\r\n$Host.SetShouldExit($LASTEXITCODE)"
79
+ @winrm_file_transporter.upload(StringIO.new(script_text_with_exit), elevated_shell_path)
74
80
  elevated_shell_path
75
81
  end
76
82
 
77
- def with_temp_file(script_text)
78
- file = Tempfile.new(['winrm-elevated-shell', 'ps1'])
79
- file.write(script_text)
80
- file.write("\r\n$Host.SetShouldExit($LASTEXITCODE)")
81
- file.fsync
82
- file.close
83
- yield file.path
84
- ensure
85
- file.close
86
- file.unlink
87
- end
88
-
89
83
  def elevated_shell_script_content
90
84
  IO.read(File.expand_path('../../winrm-elevated/scripts/elevated_shell.ps1', __dir__))
91
85
  end
92
86
 
93
87
  def wrap_in_scheduled_task(script_path, username, password)
94
- Erubis::Eruby.new(elevated_shell_script_content).result(
88
+ context = {
95
89
  username: username,
96
90
  password: password,
97
91
  script_path: script_path,
98
- interactive_logon: interactive_logon
99
- )
92
+ interactive_logon: interactive_logon,
93
+ execution_timeout: execution_timeout
94
+ }
95
+
96
+ b = binding
97
+ locals = context.collect { |k, _| "#{k} = context[#{k.inspect}]; " }
98
+ b.eval(locals.join)
99
+ b.eval(Erubi::Engine.new(elevated_shell_script_content).src)
100
100
  end
101
101
  end
102
102
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: winrm-elevated
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shawn Neal
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-19 00:00:00.000000000 Z
11
+ date: 2020-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: erubi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.8'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: winrm
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -113,15 +127,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
127
  requirements:
114
128
  - - ">="
115
129
  - !ruby/object:Gem::Version
116
- version: 2.2.0
130
+ version: 2.3.0
117
131
  required_rubygems_version: !ruby/object:Gem::Requirement
118
132
  requirements:
119
133
  - - ">="
120
134
  - !ruby/object:Gem::Version
121
135
  version: '0'
122
136
  requirements: []
123
- rubyforge_project:
124
- rubygems_version: 2.7.6
137
+ rubygems_version: 3.1.2
125
138
  signing_key:
126
139
  specification_version: 4
127
140
  summary: Ruby library for running commands as elevated