winrm-elevated 0.4.0 → 1.0.0

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,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