winrm-elevated 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,18 +1,17 @@
1
- # encoding: UTF-8
2
- #
3
- # Copyright 2015 Shawn Neal <sneal@sneal.net>
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
-
17
- require 'winrm'
18
- require_relative 'winrm/shells/elevated'
1
+ #
2
+ # Copyright 2015 Shawn Neal <sneal@sneal.net>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'winrm'
17
+ require_relative 'winrm/shells/elevated'
@@ -1,116 +1,116 @@
1
- $username = '<%= username %>'
2
- $password = '<%= password %>'
3
- $script_file = '<%= script_path %>'
4
-
5
- $interactive = '<%= interactive_logon %>'
6
- $pass_to_use = $password
7
- $logon_type = 1
8
- $logon_type_xml = "<LogonType>Password</LogonType>"
9
- if($pass_to_use.length -eq 0) {
10
- $pass_to_use = $null
11
- $logon_type = 5
12
- $logon_type_xml = ""
13
- }
14
- if($interactive -eq 'true') {
15
- $logon_type = 3
16
- $logon_type_xml = "<LogonType>InteractiveTokenOrPassword</LogonType>"
17
- }
18
-
19
- $task_name = "WinRM_Elevated_Shell"
20
- $out_file = [System.IO.Path]::GetTempFileName()
21
- $err_file = [System.IO.Path]::GetTempFileName()
22
-
23
- $task_xml = @'
24
- <?xml version="1.0" encoding="UTF-16"?>
25
- <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
26
- <Principals>
27
- <Principal id="Author">
28
- <UserId>{username}</UserId>
29
- {logon_type}
30
- <RunLevel>HighestAvailable</RunLevel>
31
- </Principal>
32
- </Principals>
33
- <Settings>
34
- <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
35
- <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
36
- <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
37
- <AllowHardTerminate>true</AllowHardTerminate>
38
- <StartWhenAvailable>false</StartWhenAvailable>
39
- <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
40
- <IdleSettings>
41
- <StopOnIdleEnd>false</StopOnIdleEnd>
42
- <RestartOnIdle>false</RestartOnIdle>
43
- </IdleSettings>
44
- <AllowStartOnDemand>true</AllowStartOnDemand>
45
- <Enabled>true</Enabled>
46
- <Hidden>false</Hidden>
47
- <RunOnlyIfIdle>false</RunOnlyIfIdle>
48
- <WakeToRun>false</WakeToRun>
49
- <ExecutionTimeLimit>PT24H</ExecutionTimeLimit>
50
- <Priority>4</Priority>
51
- </Settings>
52
- <Actions Context="Author">
53
- <Exec>
54
- <Command>cmd</Command>
55
- <Arguments>{arguments}</Arguments>
56
- </Exec>
57
- </Actions>
58
- </Task>
59
- '@
60
-
61
- $arguments = "/c powershell.exe -executionpolicy bypass -NoProfile -File $script_file &gt; $out_file 2&gt;$err_file"
62
-
63
- $task_xml = $task_xml.Replace("{arguments}", $arguments)
64
- $task_xml = $task_xml.Replace("{username}", $username)
65
- $task_xml = $task_xml.Replace("{logon_type}", $logon_type_xml)
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
73
-
74
- $registered_task = $folder.GetTask("\$task_name")
75
- $registered_task.Run($null) | Out-Null
76
-
77
- $timeout = 10
78
- $sec = 0
79
- while ( (!($registered_task.state -eq 4)) -and ($sec -lt $timeout) ) {
80
- Start-Sleep -s 1
81
- $sec++
82
- }
83
-
84
- function SlurpOutput($file, $cur_line, $out_type) {
85
- 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("$_")
92
- }
93
- }
94
- }
95
- return $cur_line
96
- }
97
-
98
- $err_cur_line = 0
99
- $out_cur_line = 0
100
- do {
101
- Start-Sleep -m 100
102
- $out_cur_line = SlurpOutput $out_file $out_cur_line 'out'
103
- $err_cur_line = SlurpOutput $err_file $err_cur_line 'err'
104
- } while (!($registered_task.state -eq 3))
105
-
106
- # We'll make a best effort to clean these files
107
- # But a reboot could possibly end the task while the process
108
- # still runs and locks the file. If we can't delete we don't want to fail
109
- try { Remove-Item $out_file -ErrorAction Stop } catch {}
110
- try { Remove-Item $err_file -ErrorAction Stop } catch {}
111
- try { Remove-Item $script_file -ErrorAction Stop } catch {}
112
-
113
- $exit_code = $registered_task.LastTaskResult
114
- [System.Runtime.Interopservices.Marshal]::ReleaseComObject($schedule) | Out-Null
115
-
116
- exit $exit_code
1
+ $username = '<%= username %>'
2
+ $password = '<%= password %>'
3
+ $script_file = '<%= script_path %>'
4
+
5
+ $interactive = '<%= interactive_logon %>'
6
+ $pass_to_use = $password
7
+ $logon_type = 1
8
+ $logon_type_xml = "<LogonType>Password</LogonType>"
9
+ if($pass_to_use.length -eq 0) {
10
+ $pass_to_use = $null
11
+ $logon_type = 5
12
+ $logon_type_xml = ""
13
+ }
14
+ if($interactive -eq 'true') {
15
+ $logon_type = 3
16
+ $logon_type_xml = "<LogonType>InteractiveTokenOrPassword</LogonType>"
17
+ }
18
+
19
+ $task_name = "WinRM_Elevated_Shell"
20
+ $out_file = [System.IO.Path]::GetTempFileName()
21
+ $err_file = [System.IO.Path]::GetTempFileName()
22
+
23
+ $task_xml = @'
24
+ <?xml version="1.0" encoding="UTF-16"?>
25
+ <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
26
+ <Principals>
27
+ <Principal id="Author">
28
+ <UserId>{username}</UserId>
29
+ {logon_type}
30
+ <RunLevel>HighestAvailable</RunLevel>
31
+ </Principal>
32
+ </Principals>
33
+ <Settings>
34
+ <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
35
+ <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
36
+ <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
37
+ <AllowHardTerminate>true</AllowHardTerminate>
38
+ <StartWhenAvailable>false</StartWhenAvailable>
39
+ <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
40
+ <IdleSettings>
41
+ <StopOnIdleEnd>false</StopOnIdleEnd>
42
+ <RestartOnIdle>false</RestartOnIdle>
43
+ </IdleSettings>
44
+ <AllowStartOnDemand>true</AllowStartOnDemand>
45
+ <Enabled>true</Enabled>
46
+ <Hidden>false</Hidden>
47
+ <RunOnlyIfIdle>false</RunOnlyIfIdle>
48
+ <WakeToRun>false</WakeToRun>
49
+ <ExecutionTimeLimit>PT24H</ExecutionTimeLimit>
50
+ <Priority>4</Priority>
51
+ </Settings>
52
+ <Actions Context="Author">
53
+ <Exec>
54
+ <Command>cmd</Command>
55
+ <Arguments>{arguments}</Arguments>
56
+ </Exec>
57
+ </Actions>
58
+ </Task>
59
+ '@
60
+
61
+ $arguments = "/c powershell.exe -executionpolicy bypass -NoProfile -File $script_file &gt; $out_file 2&gt;$err_file"
62
+
63
+ $task_xml = $task_xml.Replace("{arguments}", $arguments)
64
+ $task_xml = $task_xml.Replace("{username}", $username)
65
+ $task_xml = $task_xml.Replace("{logon_type}", $logon_type_xml)
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
73
+
74
+ $registered_task = $folder.GetTask("\$task_name")
75
+ $registered_task.Run($null) | Out-Null
76
+
77
+ $timeout = 10
78
+ $sec = 0
79
+ while ( (!($registered_task.state -eq 4)) -and ($sec -lt $timeout) ) {
80
+ Start-Sleep -s 1
81
+ $sec++
82
+ }
83
+
84
+ function SlurpOutput($file, $cur_line, $out_type) {
85
+ 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("$_")
92
+ }
93
+ }
94
+ }
95
+ return $cur_line
96
+ }
97
+
98
+ $err_cur_line = 0
99
+ $out_cur_line = 0
100
+ do {
101
+ Start-Sleep -m 100
102
+ $out_cur_line = SlurpOutput $out_file $out_cur_line 'out'
103
+ $err_cur_line = SlurpOutput $err_file $err_cur_line 'err'
104
+ } while (!($registered_task.state -eq 3))
105
+
106
+ # We'll make a best effort to clean these files
107
+ # But a reboot could possibly end the task while the process
108
+ # still runs and locks the file. If we can't delete we don't want to fail
109
+ try { Remove-Item $out_file -ErrorAction Stop } catch {}
110
+ try { Remove-Item $err_file -ErrorAction Stop } catch {}
111
+ try { Remove-Item $script_file -ErrorAction Stop } catch {}
112
+
113
+ $exit_code = $registered_task.LastTaskResult
114
+ [System.Runtime.Interopservices.Marshal]::ReleaseComObject($schedule) | Out-Null
115
+
116
+ exit $exit_code
@@ -1,104 +1,103 @@
1
- # encoding: UTF-8
2
- #
3
- # Copyright 2015 Shawn Neal <sneal@sneal.net>
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
-
17
- require 'erubis'
18
- require 'winrm'
19
- require 'winrm-fs'
20
- require 'securerandom'
21
-
22
- module WinRM
23
- module Shells
24
- # Runs PowerShell commands elevated via a scheduled task
25
- class Elevated
26
- # Create a new elevated shell
27
- # @param connection_opts [ConnectionOpts] The WinRM connection options
28
- # @param transport [HttpTransport] The WinRM SOAP transport
29
- # @param logger [Logger] The logger to log diagnostic messages to
30
- def initialize(connection_opts, transport, logger)
31
- @logger = logger
32
- @username = connection_opts[:user]
33
- @password = connection_opts[:password]
34
- @interactive_logon = false
35
- @shell = Powershell.new(connection_opts, transport, logger)
36
- @winrm_file_transporter = WinRM::FS::Core::FileTransporter.new(@shell)
37
- end
38
-
39
- # @return [String] The admin user name to execute the scheduled task as
40
- attr_accessor :username
41
-
42
- # @return [String] The admin user password
43
- attr_accessor :password
44
-
45
- # @return [Bool] Using an interactive logon
46
- attr_accessor :interactive_logon
47
-
48
- # Run a command or PowerShell script elevated without any of the
49
- # restrictions that WinRM puts in place.
50
- #
51
- # @param [String] The command or PS script to wrap in a scheduled task
52
- #
53
- # @return [WinRM::Output] :stdout and :stderr
54
- def run(command, &block)
55
- # if an IO object is passed read it, otherwise assume the contents of the file were passed
56
- script_text = command.respond_to?(:read) ? command.read : command
57
-
58
- script_path = upload_elevated_shell_script(script_text)
59
- wrapped_script = wrap_in_scheduled_task(script_path, username, password)
60
- @shell.run(wrapped_script, &block)
61
- end
62
-
63
- # Closes the shell if one is open
64
- def close
65
- @shell.close
66
- end
67
-
68
- private
69
-
70
- def upload_elevated_shell_script(script_text)
71
- elevated_shell_path = 'c:/windows/temp/winrm-elevated-shell-' + SecureRandom.uuid + '.ps1'
72
- with_temp_file(script_text) do |temp_file|
73
- @winrm_file_transporter.upload(temp_file, elevated_shell_path)
74
- end
75
- elevated_shell_path
76
- end
77
-
78
- def with_temp_file(script_text)
79
- file = Tempfile.new(['winrm-elevated-shell', 'ps1'])
80
- file.write(script_text)
81
- file.write("\r\n$Host.SetShouldExit($LASTEXITCODE)")
82
- file.fsync
83
- file.close
84
- yield file.path
85
- ensure
86
- file.close
87
- file.unlink
88
- end
89
-
90
- def elevated_shell_script_content
91
- IO.read(File.expand_path('../../../winrm-elevated/scripts/elevated_shell.ps1', __FILE__))
92
- end
93
-
94
- def wrap_in_scheduled_task(script_path, username, password)
95
- Erubis::Eruby.new(elevated_shell_script_content).result(
96
- username: username,
97
- password: password,
98
- script_path: script_path,
99
- interactive_logon: interactive_logon
100
- )
101
- end
102
- end
103
- end
104
- end
1
+ #
2
+ # Copyright 2015 Shawn Neal <sneal@sneal.net>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'erubis'
17
+ require 'winrm'
18
+ require 'winrm-fs'
19
+ require 'securerandom'
20
+
21
+ module WinRM
22
+ module Shells
23
+ # Runs PowerShell commands elevated via a scheduled task
24
+ class Elevated
25
+ # Create a new elevated shell
26
+ # @param connection_opts [ConnectionOpts] The WinRM connection options
27
+ # @param transport [HttpTransport] The WinRM SOAP transport
28
+ # @param logger [Logger] The logger to log diagnostic messages to
29
+ def initialize(connection_opts, transport, logger)
30
+ @logger = logger
31
+ @username = connection_opts[:user]
32
+ @password = connection_opts[:password]
33
+ @interactive_logon = false
34
+ @shell = Powershell.new(connection_opts, transport, logger)
35
+ @winrm_file_transporter = WinRM::FS::Core::FileTransporter.new(@shell)
36
+ end
37
+
38
+ # @return [String] The admin user name to execute the scheduled task as
39
+ attr_accessor :username
40
+
41
+ # @return [String] The admin user password
42
+ attr_accessor :password
43
+
44
+ # @return [Bool] Using an interactive logon
45
+ attr_accessor :interactive_logon
46
+
47
+ # Run a command or PowerShell script elevated without any of the
48
+ # restrictions that WinRM puts in place.
49
+ #
50
+ # @param [String] The command or PS script to wrap in a scheduled task
51
+ #
52
+ # @return [WinRM::Output] :stdout and :stderr
53
+ def run(command, &block)
54
+ # if an IO object is passed read it, otherwise assume the contents of the file were passed
55
+ script_text = command.respond_to?(:read) ? command.read : command
56
+
57
+ script_path = upload_elevated_shell_script(script_text)
58
+ wrapped_script = wrap_in_scheduled_task(script_path, username, password)
59
+ @shell.run(wrapped_script, &block)
60
+ end
61
+
62
+ # Closes the shell if one is open
63
+ def close
64
+ @shell.close
65
+ end
66
+
67
+ private
68
+
69
+ def upload_elevated_shell_script(script_text)
70
+ 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
74
+ elevated_shell_path
75
+ end
76
+
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
+ def elevated_shell_script_content
90
+ IO.read(File.expand_path('../../winrm-elevated/scripts/elevated_shell.ps1', __dir__))
91
+ end
92
+
93
+ def wrap_in_scheduled_task(script_path, username, password)
94
+ Erubis::Eruby.new(elevated_shell_script_content).result(
95
+ username: username,
96
+ password: password,
97
+ script_path: script_path,
98
+ interactive_logon: interactive_logon
99
+ )
100
+ end
101
+ end
102
+ end
103
+ end