winrm-elevated 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,105 +1,108 @@
1
- param([String]$username, [String]$password, [String]$encoded_command)
2
-
3
- $pass_to_use = $password
4
- $logon_type = 1
5
- $logon_type_xml = "<LogonType>Password</LogonType>"
6
- if($pass_to_use.length -eq 0) {
7
- $pass_to_use = $null
8
- $logon_type = 5
9
- $logon_type_xml = ""
10
- }
11
-
12
- $task_name = "WinRM_Elevated_Shell"
13
- $out_file = [System.IO.Path]::GetTempFileName()
14
- $err_file = [System.IO.Path]::GetTempFileName()
15
-
16
- $task_xml = @'
17
- <?xml version="1.0" encoding="UTF-16"?>
18
- <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
19
- <Principals>
20
- <Principal id="Author">
21
- <UserId>{username}</UserId>
22
- {logon_type}
23
- <RunLevel>HighestAvailable</RunLevel>
24
- </Principal>
25
- </Principals>
26
- <Settings>
27
- <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
28
- <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
29
- <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
30
- <AllowHardTerminate>true</AllowHardTerminate>
31
- <StartWhenAvailable>false</StartWhenAvailable>
32
- <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
33
- <IdleSettings>
34
- <StopOnIdleEnd>false</StopOnIdleEnd>
35
- <RestartOnIdle>false</RestartOnIdle>
36
- </IdleSettings>
37
- <AllowStartOnDemand>true</AllowStartOnDemand>
38
- <Enabled>true</Enabled>
39
- <Hidden>false</Hidden>
40
- <RunOnlyIfIdle>false</RunOnlyIfIdle>
41
- <WakeToRun>false</WakeToRun>
42
- <ExecutionTimeLimit>PT24H</ExecutionTimeLimit>
43
- <Priority>4</Priority>
44
- </Settings>
45
- <Actions Context="Author">
46
- <Exec>
47
- <Command>cmd</Command>
48
- <Arguments>{arguments}</Arguments>
49
- </Exec>
50
- </Actions>
51
- </Task>
52
- '@
53
-
54
- $arguments = "/c powershell.exe -EncodedCommand $encoded_command &gt; $out_file 2&gt;$err_file"
55
-
56
- $task_xml = $task_xml.Replace("{arguments}", $arguments)
57
- $task_xml = $task_xml.Replace("{username}", $username)
58
- $task_xml = $task_xml.Replace("{logon_type}", $logon_type_xml)
59
-
60
- $schedule = New-Object -ComObject "Schedule.Service"
61
- $schedule.Connect()
62
- $task = $schedule.NewTask($null)
63
- $task.XmlText = $task_xml
64
- $folder = $schedule.GetFolder("\")
65
- $folder.RegisterTaskDefinition($task_name, $task, 6, $username, $pass_to_use, $logon_type, $null) | Out-Null
66
-
67
- $registered_task = $folder.GetTask("\$task_name")
68
- $registered_task.Run($null) | Out-Null
69
-
70
- $timeout = 10
71
- $sec = 0
72
- while ( (!($registered_task.state -eq 4)) -and ($sec -lt $timeout) ) {
73
- Start-Sleep -s 1
74
- $sec++
75
- }
76
-
77
- function SlurpOutput($file, $cur_line, $out_type) {
78
- if (Test-Path $file) {
79
- get-content $file | select -skip $cur_line | ForEach {
80
- $cur_line += 1
81
- if ($out_type -eq 'err') {
82
- $host.ui.WriteErrorLine("$_")
83
- } else {
84
- $host.ui.WriteLine("$_")
85
- }
86
- }
87
- }
88
- return $cur_line
89
- }
90
-
91
- $err_cur_line = 0
92
- $out_cur_line = 0
93
- do {
94
- Start-Sleep -m 100
95
- $out_cur_line = SlurpOutput $out_file $out_cur_line 'out'
96
- $err_cur_line = SlurpOutput $err_file $err_cur_line 'err'
97
- } while (!($registered_task.state -eq 3))
98
-
99
- del $out_file
100
- del $err_file
101
-
102
- $exit_code = $registered_task.LastTaskResult
103
- [System.Runtime.Interopservices.Marshal]::ReleaseComObject($schedule) | Out-Null
104
-
105
- exit $exit_code
1
+ $username = "<%= username %>"
2
+ $password = "<%= password %>"
3
+ $script_file = "<%= script_path %>"
4
+
5
+ $pass_to_use = $password
6
+ $logon_type = 1
7
+ $logon_type_xml = "<LogonType>Password</LogonType>"
8
+ if($pass_to_use.length -eq 0) {
9
+ $pass_to_use = $null
10
+ $logon_type = 5
11
+ $logon_type_xml = ""
12
+ }
13
+
14
+ $task_name = "WinRM_Elevated_Shell"
15
+ $out_file = [System.IO.Path]::GetTempFileName()
16
+ $err_file = [System.IO.Path]::GetTempFileName()
17
+
18
+ $task_xml = @'
19
+ <?xml version="1.0" encoding="UTF-16"?>
20
+ <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
21
+ <Principals>
22
+ <Principal id="Author">
23
+ <UserId>{username}</UserId>
24
+ {logon_type}
25
+ <RunLevel>HighestAvailable</RunLevel>
26
+ </Principal>
27
+ </Principals>
28
+ <Settings>
29
+ <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
30
+ <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
31
+ <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
32
+ <AllowHardTerminate>true</AllowHardTerminate>
33
+ <StartWhenAvailable>false</StartWhenAvailable>
34
+ <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
35
+ <IdleSettings>
36
+ <StopOnIdleEnd>false</StopOnIdleEnd>
37
+ <RestartOnIdle>false</RestartOnIdle>
38
+ </IdleSettings>
39
+ <AllowStartOnDemand>true</AllowStartOnDemand>
40
+ <Enabled>true</Enabled>
41
+ <Hidden>false</Hidden>
42
+ <RunOnlyIfIdle>false</RunOnlyIfIdle>
43
+ <WakeToRun>false</WakeToRun>
44
+ <ExecutionTimeLimit>PT24H</ExecutionTimeLimit>
45
+ <Priority>4</Priority>
46
+ </Settings>
47
+ <Actions Context="Author">
48
+ <Exec>
49
+ <Command>cmd</Command>
50
+ <Arguments>{arguments}</Arguments>
51
+ </Exec>
52
+ </Actions>
53
+ </Task>
54
+ '@
55
+
56
+ $arguments = "/c powershell.exe -File $script_file &gt; $out_file 2&gt;$err_file"
57
+
58
+ $task_xml = $task_xml.Replace("{arguments}", $arguments)
59
+ $task_xml = $task_xml.Replace("{username}", $username)
60
+ $task_xml = $task_xml.Replace("{logon_type}", $logon_type_xml)
61
+
62
+ $schedule = New-Object -ComObject "Schedule.Service"
63
+ $schedule.Connect()
64
+ $task = $schedule.NewTask($null)
65
+ $task.XmlText = $task_xml
66
+ $folder = $schedule.GetFolder("\")
67
+ $folder.RegisterTaskDefinition($task_name, $task, 6, $username, $pass_to_use, $logon_type, $null) | Out-Null
68
+
69
+ $registered_task = $folder.GetTask("\$task_name")
70
+ $registered_task.Run($null) | Out-Null
71
+
72
+ $timeout = 10
73
+ $sec = 0
74
+ while ( (!($registered_task.state -eq 4)) -and ($sec -lt $timeout) ) {
75
+ Start-Sleep -s 1
76
+ $sec++
77
+ }
78
+
79
+ function SlurpOutput($file, $cur_line, $out_type) {
80
+ if (Test-Path $file) {
81
+ get-content $file | select -skip $cur_line | ForEach {
82
+ $cur_line += 1
83
+ if ($out_type -eq 'err') {
84
+ $host.ui.WriteErrorLine("$_")
85
+ } else {
86
+ $host.ui.WriteLine("$_")
87
+ }
88
+ }
89
+ }
90
+ return $cur_line
91
+ }
92
+
93
+ $err_cur_line = 0
94
+ $out_cur_line = 0
95
+ do {
96
+ Start-Sleep -m 100
97
+ $out_cur_line = SlurpOutput $out_file $out_cur_line 'out'
98
+ $err_cur_line = SlurpOutput $err_file $err_cur_line 'err'
99
+ } while (!($registered_task.state -eq 3))
100
+
101
+ del $out_file
102
+ del $err_file
103
+ del $script_file
104
+
105
+ $exit_code = $registered_task.LastTaskResult
106
+ [System.Runtime.Interopservices.Marshal]::ReleaseComObject($schedule) | Out-Null
107
+
108
+ exit $exit_code
@@ -1,25 +1,18 @@
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-elevated/runner'
19
-
20
- module WinRM
21
- # WinRM File System
22
- module Elevated
23
- # Top level module code
24
- end
25
- end
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,5 +1,3 @@
1
- auth_type: plaintext
2
- endpoint: "http://localhost:55985/wsman"
3
- options:
4
- user: vagrant
5
- pass: vagrant
1
+ endpoint: "http://localhost:55985/wsman"
2
+ user: vagrant
3
+ password: vagrant
data/spec/matchers.rb CHANGED
@@ -1,64 +1,50 @@
1
- # encoding: UTF-8
2
- require 'rspec/expectations'
3
-
4
- # rspec matchers
5
- module WinRMSpecs
6
- def self.stdout(output)
7
- output[:data].collect do |i|
8
- i[:stdout]
9
- end.join('\r\n').gsub(/(\\r\\n)+$/, '')
10
- end
11
-
12
- def self.stderr(output)
13
- output[:data].collect do |i|
14
- i[:stderr]
15
- end.join('\r\n').gsub(/(\\r\\n)+$/, '')
16
- end
17
- end
18
-
19
- RSpec::Matchers.define :have_stdout_match do |expected_stdout|
20
- match do |actual_output|
21
- !expected_stdout.match(WinRMSpecs.stdout(actual_output)).nil?
22
- end
23
- failure_message do |actual_output|
24
- "expected that '#{WinRMSpecs.stdout(actual_output)}' would match #{expected_stdout}"
25
- end
26
- end
27
-
28
- RSpec::Matchers.define :have_stderr_match do |expected_stderr|
29
- match do |actual_output|
30
- !expected_stderr.match(WinRMSpecs.stderr(actual_output)).nil?
31
- end
32
- failure_message do |actual_output|
33
- "expected that '#{WinRMSpecs.stderr(actual_output)}' would match #{expected_stderr}"
34
- end
35
- end
36
-
37
- RSpec::Matchers.define :have_no_stdout do
38
- match do |actual_output|
39
- stdout = WinRMSpecs.stdout(actual_output)
40
- stdout == '\r\n' || stdout == ''
41
- end
42
- failure_message do |actual_output|
43
- "expected that '#{WinRMSpecs.stdout(actual_output)}' would have no stdout"
44
- end
45
- end
46
-
47
- RSpec::Matchers.define :have_no_stderr do
48
- match do |actual_output|
49
- stderr = WinRMSpecs.stderr(actual_output)
50
- stderr == '\r\n' || stderr == ''
51
- end
52
- failure_message do |actual_output|
53
- "expected that '#{WinRMSpecs.stderr(actual_output)}' would have no stderr"
54
- end
55
- end
56
-
57
- RSpec::Matchers.define :have_exit_code do |expected_exit_code|
58
- match do |actual_output|
59
- expected_exit_code == actual_output[:exitcode]
60
- end
61
- failure_message do |actual_output|
62
- "expected exit code #{expected_exit_code}, but got #{actual_output[:exitcode]}"
63
- end
64
- end
1
+ # encoding: UTF-8
2
+ require 'rspec/expectations'
3
+
4
+ # rspec matchers
5
+ RSpec::Matchers.define :have_stdout_match do |expected_stdout|
6
+ match do |actual_output|
7
+ !expected_stdout.match(actual_output.stdout).nil?
8
+ end
9
+ failure_message do |actual_output|
10
+ "expected that '#{actual_output.stdout}' would match #{expected_stdout}"
11
+ end
12
+ end
13
+
14
+ RSpec::Matchers.define :have_stderr_match do |expected_stderr|
15
+ match do |actual_output|
16
+ !expected_stderr.match(actual_output.stderr).nil?
17
+ end
18
+ failure_message do |actual_output|
19
+ "expected that '#{actual_output.stderr}' would match #{expected_stderr}"
20
+ end
21
+ end
22
+
23
+ RSpec::Matchers.define :have_no_stdout do
24
+ match do |actual_output|
25
+ stdout = actual_output.stdout
26
+ stdout == '\r\n' || stdout == ''
27
+ end
28
+ failure_message do |actual_output|
29
+ "expected that '#{actual_output.stdout}' would have no stdout"
30
+ end
31
+ end
32
+
33
+ RSpec::Matchers.define :have_no_stderr do
34
+ match do |actual_output|
35
+ stderr = actual_output.stderr
36
+ stderr == '\r\n' || stderr == ''
37
+ end
38
+ failure_message do |actual_output|
39
+ "expected that '#{actual_output.stderr}' would have no stderr"
40
+ end
41
+ end
42
+
43
+ RSpec::Matchers.define :have_exit_code do |expected_exit_code|
44
+ match do |actual_output|
45
+ expected_exit_code == actual_output.exitcode
46
+ end
47
+ failure_message do |actual_output|
48
+ "expected exit code #{expected_exit_code}, but got #{actual_output.exitcode}"
49
+ end
50
+ end
@@ -1,93 +1,87 @@
1
- # encoding: UTF-8
2
- describe 'powershell elevated runner', integration: true do
3
- describe 'ipconfig' do
4
- subject(:output) { elevated_runner.powershell_elevated('ipconfig', username, password) }
5
- it { should have_exit_code 0 }
6
- it { should have_stdout_match(/Windows IP Configuration/) }
7
- it { should have_no_stderr }
8
- end
9
-
10
- describe 'ipconfig as Service' do
11
- subject(:output) { elevated_runner.powershell_elevated('ipconfig', 'System', nil) }
12
- it { should have_exit_code 0 }
13
- it { should have_stdout_match(/Windows IP Configuration/) }
14
- it { should have_no_stderr }
15
- end
16
-
17
- describe 'echo \'hello world\' using apostrophes' do
18
- subject(:output) { elevated_runner.powershell_elevated("echo 'hello world'", username, password) }
19
- it { should have_exit_code 0 }
20
- it { should have_stdout_match(/hello world/) }
21
- it { should have_no_stderr }
22
- end
23
-
24
- describe 'ipconfig with incorrect argument -z' do
25
- subject(:output) { elevated_runner.powershell_elevated('ipconfig 127.0.0.1 -z', username, password) }
26
- it { should have_exit_code 1 }
27
- end
28
-
29
- describe 'Math area calculation' do
30
- subject(:output) do
31
- cmd = <<-EOH
32
- $diameter = 4.5
33
- $area = [Math]::pow([Math]::PI * ($diameter/2), 2)
34
- Write-Host $area
35
- EOH
36
- elevated_runner.powershell_elevated(cmd, username, password)
37
- end
38
- it { should have_exit_code 0 }
39
- it { should have_stdout_match(/49.9648722805149/) }
40
- it { should have_no_stderr }
41
- end
42
-
43
- describe 'ipconfig with a block' do
44
- subject(:stdout) do
45
- outvar = ''
46
- elevated_runner.powershell_elevated('ipconfig', username, password) do |stdout, _stderr|
47
- outvar << stdout
48
- end
49
- outvar
50
- end
51
- it { should match(/Windows IP Configuration/) }
52
- end
53
-
54
- describe 'capturing output from Write-Host and Write-Error' do
55
- subject(:output) do
56
- script = <<-eos
57
- Write-Host 'Hello'
58
- $host.ui.WriteErrorLine(', world!')
59
- eos
60
-
61
- @captured_stdout = ''
62
- @captured_stderr = ''
63
- elevated_runner.powershell_elevated(script, username, password) do |stdout, stderr|
64
- @captured_stdout << stdout if stdout
65
- @captured_stderr << stderr if stderr
66
- end
67
- end
68
-
69
- it 'should have stdout' do
70
- expect(output.stdout).to eq("Hello\r\n")
71
- expect(output.stdout).to eq(@captured_stdout)
72
- end
73
-
74
- it 'should have stderr' do
75
- # TODO: Option to parse CLIXML
76
- # expect(output.output).to eq("Hello\n, world!")
77
- # expect(output.stderr).to eq(", world!")
78
- expect(output.stderr).to eq(
79
- "#< CLIXML\r\n<Objs Version=\"1.1.0.1\" " \
80
- "xmlns=\"http://schemas.microsoft.com/powershell/2004/04\">" \
81
- "<S S=\"Error\">, world!_x000D__x000A_</S></Objs>\r\n")
82
- expect(output.stderr).to eq(@captured_stderr)
83
- end
84
-
85
- it 'should have output' do
86
- # TODO: Option to parse CLIXML
87
- # expect(output.output).to eq("Hello\n, world!")
88
- expect(output.output).to eq("Hello\r\n#< CLIXML\r\n<Objs Version=\"1.1.0.1\" " \
89
- "xmlns=\"http://schemas.microsoft.com/powershell/2004/04\">" \
90
- "<S S=\"Error\">, world!_x000D__x000A_</S></Objs>\r\n")
91
- end
92
- end
93
- end
1
+ # encoding: UTF-8
2
+ describe 'powershell elevated runner', integration: true do
3
+ describe 'ipconfig' do
4
+ subject(:output) { elevated_shell.run('ipconfig') }
5
+ it { should have_exit_code 0 }
6
+ it { should have_stdout_match(/Windows IP Configuration/) }
7
+ it { should have_no_stderr }
8
+ end
9
+
10
+ describe 'ipconfig as Service' do
11
+ subject(:output) do
12
+ elevated_shell.username = 'System'
13
+ elevated_shell.password = nil
14
+ elevated_shell.run('ipconfig')
15
+ end
16
+ it { should have_exit_code 0 }
17
+ it { should have_stdout_match(/Windows IP Configuration/) }
18
+ it { should have_no_stderr }
19
+ end
20
+
21
+ describe 'echo \'hello world\' using apostrophes' do
22
+ subject(:output) { elevated_shell.run("echo 'hello world'") }
23
+ it { should have_exit_code 0 }
24
+ it { should have_stdout_match(/hello world/) }
25
+ it { should have_no_stderr }
26
+ end
27
+
28
+ describe 'ipconfig with incorrect argument -z' do
29
+ subject(:output) { elevated_shell.run('ipconfig 127.0.0.1 -z') }
30
+ it { should have_exit_code 1 }
31
+ end
32
+
33
+ describe 'Math area calculation' do
34
+ subject(:output) do
35
+ cmd = <<-EOH
36
+ $diameter = 4.5
37
+ $area = [Math]::pow([Math]::PI * ($diameter/2), 2)
38
+ Write-Host $area
39
+ EOH
40
+ elevated_shell.run(cmd)
41
+ end
42
+ it { should have_exit_code 0 }
43
+ it { should have_stdout_match(/49.9648722805149/) }
44
+ it { should have_no_stderr }
45
+ end
46
+
47
+ describe 'ipconfig with a block' do
48
+ subject(:stdout) do
49
+ outvar = ''
50
+ elevated_shell.run('ipconfig') do |stdout, _stderr|
51
+ outvar << stdout
52
+ end
53
+ outvar
54
+ end
55
+ it { should match(/Windows IP Configuration/) }
56
+ end
57
+
58
+ describe 'capturing output from Write-Host and Write-Error' do
59
+ subject(:output) do
60
+ script = <<-eos
61
+ Write-Host 'Hello'
62
+ $host.ui.WriteErrorLine(', world!')
63
+ eos
64
+
65
+ @captured_stdout = ''
66
+ @captured_stderr = ''
67
+ elevated_shell.run(script) do |stdout, stderr|
68
+ @captured_stdout << stdout if stdout
69
+ @captured_stderr << stderr if stderr
70
+ end
71
+ end
72
+
73
+ it 'should have stdout' do
74
+ expect(output.stdout).to eq("Hello\r\n")
75
+ expect(output.stdout).to eq(@captured_stdout)
76
+ end
77
+
78
+ it 'should have stderr' do
79
+ expect(output.stderr).to eq(", world!\r\n")
80
+ expect(output.stderr).to eq(@captured_stderr)
81
+ end
82
+
83
+ it 'should have output' do
84
+ expect(output.output).to eq("Hello\r\n, world!\r\n")
85
+ end
86
+ end
87
+ end