kitchen-pester 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/.kitchen.appveyor.yml +21 -0
- data/.kitchen.yml +18 -0
- data/Gemfile +3 -0
- data/README.md +2 -0
- data/appveyor.yml +40 -0
- data/kitchen-pester.gemspec +2 -2
- data/lib/kitchen/verifier/pester.rb +110 -86
- data/lib/kitchen/verifier/pester_version.rb +1 -1
- data/provision.ps1 +1 -0
- data/spec/pester/pester_spec.rb +21 -0
- data/test/integration/default/pester/default.tests.ps1 +9 -0
- metadata +16 -11
- data/lib/support/powershell/NamedPipes/NamedPipes.psm1 +0 -134
- data/lib/support/powershell/ScheduledTaskRunner/ScheduledTaskRunner.psm1 +0 -92
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 421eadf1234bee4ba4c005a01170aad9ca42fca2
|
4
|
+
data.tar.gz: 16d3c4a119588ca4e18687dacfb061a8d5505af9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ded4f947b8dc8683145ffe618863ac3402ce8f191249356db0684ac4cc253c010552162d969e88c54e65eaa9be4dbee664e4ed38485c65218021b4364fe56f0f
|
7
|
+
data.tar.gz: 5ea4de348f55b4417c9da25e92232b555c5525e1fc6b4f548dad8f22506bd8de1c892278f6b3967ec6596ea66cc11aeef51f15f6c642fff0d3b272d17a987ac2
|
data/.gitignore
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
driver:
|
3
|
+
name: proxy
|
4
|
+
host: localhost
|
5
|
+
reset_command: "exit 0"
|
6
|
+
port: 5985
|
7
|
+
username: <%= ENV["machine_user"] %>
|
8
|
+
password: <%= ENV["machine_pass"] %>
|
9
|
+
|
10
|
+
provisioner:
|
11
|
+
name: shell
|
12
|
+
script: provision.ps1
|
13
|
+
|
14
|
+
platforms:
|
15
|
+
- name: windows-2012R2
|
16
|
+
|
17
|
+
verifier:
|
18
|
+
name: pester
|
19
|
+
|
20
|
+
suites:
|
21
|
+
- name: default
|
data/.kitchen.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
[![Build status](https://ci.appveyor.com/api/projects/status/a63wtd8qpxe5bt4e/branch/master?svg=true)](https://ci.appveyor.com/project/test-kitchen/kitchen-pester/branch/master)
|
1
2
|
[![Gem Version](https://badge.fury.io/rb/kitchen-pester.svg)](http://badge.fury.io/rb/kitchen-pester)
|
3
|
+
|
2
4
|
# Kitchen::Pester
|
3
5
|
|
4
6
|
Execute [Pester](https://github.com/pester/Pester) tests right from Test-Kitchen, without having to transit the Busser layer.
|
data/appveyor.yml
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
version: "master-{build}"
|
2
|
+
|
3
|
+
os: Windows Server 2012 R2
|
4
|
+
platform:
|
5
|
+
- x64
|
6
|
+
|
7
|
+
environment:
|
8
|
+
machine_user: test_user
|
9
|
+
machine_pass: Pass@word1
|
10
|
+
KITCHEN_YAML: .kitchen.appveyor.yml
|
11
|
+
|
12
|
+
matrix:
|
13
|
+
- ruby_version: "23"
|
14
|
+
|
15
|
+
branches:
|
16
|
+
only:
|
17
|
+
- master
|
18
|
+
|
19
|
+
# Do not build on tags (GitHub only)
|
20
|
+
skip_tags: true
|
21
|
+
|
22
|
+
#faster cloning
|
23
|
+
clone_depth: 1
|
24
|
+
|
25
|
+
# Install the latest nightly of ChefDK
|
26
|
+
install:
|
27
|
+
- ps: net user /add $env:machine_user $env:machine_pass
|
28
|
+
- ps: net localgroup administrators $env:machine_user /add
|
29
|
+
- ps: $env:PATH="C:\Ruby$env:ruby_version\bin;$env:PATH"
|
30
|
+
- ps: Write-Host $env:PATH
|
31
|
+
- ps: ruby --version
|
32
|
+
- ps: gem --version
|
33
|
+
- ps: gem install bundler --quiet --no-ri --no-rdoc
|
34
|
+
- ps: bundler --version
|
35
|
+
|
36
|
+
build_script:
|
37
|
+
- bundle install || bundle install || bundle install
|
38
|
+
|
39
|
+
test_script:
|
40
|
+
- bundle exec kitchen verify
|
data/kitchen-pester.gemspec
CHANGED
@@ -20,8 +20,8 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
22
|
spec.add_development_dependency "bundler", "~> 1.7"
|
23
|
-
spec.add_development_dependency "rake", "~>
|
23
|
+
spec.add_development_dependency "rake", "~> 11.3"
|
24
24
|
spec.add_development_dependency "pry", "~> 0.10"
|
25
25
|
|
26
|
-
spec.add_dependency "test-kitchen", "~> 1.
|
26
|
+
spec.add_dependency "test-kitchen", "~> 1.10"
|
27
27
|
end
|
@@ -32,7 +32,6 @@ module Kitchen
|
|
32
32
|
|
33
33
|
default_config :restart_winrm, false
|
34
34
|
default_config :test_folder
|
35
|
-
default_config :run_as_scheduled_task, false
|
36
35
|
default_config :use_local_pester_module, false
|
37
36
|
|
38
37
|
# Creates a new Verifier object using the provided configuration data
|
@@ -65,6 +64,7 @@ module Kitchen
|
|
65
64
|
super
|
66
65
|
prepare_powershell_modules
|
67
66
|
prepare_pester_tests
|
67
|
+
prepare_helpers
|
68
68
|
end
|
69
69
|
|
70
70
|
# Generates a command string which will install and configure the
|
@@ -105,14 +105,7 @@ module Kitchen
|
|
105
105
|
# @return [String] a command string
|
106
106
|
def run_command
|
107
107
|
return if local_suite_files.empty?
|
108
|
-
|
109
|
-
cmd = if config[:run_as_scheduled_task]
|
110
|
-
wrap_scheduled_task('verify-run', run_command_script)
|
111
|
-
else
|
112
|
-
run_command_script
|
113
|
-
end
|
114
|
-
|
115
|
-
really_wrap_shell_code(cmd)
|
108
|
+
really_wrap_shell_code(run_command_script)
|
116
109
|
end
|
117
110
|
|
118
111
|
#private
|
@@ -135,92 +128,94 @@ module Kitchen
|
|
135
128
|
<<-EOH
|
136
129
|
set-executionpolicy unrestricted -force;
|
137
130
|
$global:ProgressPreference = 'SilentlyContinue'
|
138
|
-
#{"$VerbosePreference = 'Continue'" if instance.logger.logdev.level == 0}
|
139
131
|
$env:psmodulepath += ";$(join-path (resolve-path $env:temp).path 'verifier/modules')";
|
140
|
-
# $env:psmodulepath -split ';' | % {write-output "PSModulePath contains:"} {write-output "`t$_"}
|
141
132
|
#{script}
|
142
133
|
EOH
|
143
134
|
end
|
144
135
|
|
145
|
-
def
|
146
|
-
(0...8).map { (65 + rand(26)).chr }.join
|
147
|
-
end
|
148
|
-
|
149
|
-
def wrap_scheduled_task (name, script)
|
150
|
-
randomized_name = "#{name}-#{random_string}"
|
136
|
+
def install_command_script
|
151
137
|
<<-EOH
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
$
|
157
|
-
|
158
|
-
Invoke-ScheduledTaskCommand -name #{randomized_name}
|
159
|
-
$ExitCode = Get-ScheduledTaskExitCode -name #{randomized_name}
|
160
|
-
Remove-ScheduledTaskCommand -name #{randomized_name}
|
161
|
-
$TestResultPath = "#{File.join(config[:root_path], 'pester/result.xml')}"
|
162
|
-
$TestResults = import-clixml $TestResultPath
|
163
|
-
Write-Host
|
164
|
-
ConvertFrom-PesterOutputObject $TestResults
|
165
|
-
Write-Host
|
166
|
-
$host.SetShouldExit($ExitCode)
|
167
|
-
EOH
|
168
|
-
end
|
138
|
+
function directory($path){
|
139
|
+
if (test-path $path) {(resolve-path $path).providerpath}
|
140
|
+
else {(resolve-path (mkdir $path)).providerpath}
|
141
|
+
}
|
142
|
+
$VerifierModulePath = directory $env:temp/verifier/modules
|
143
|
+
$VerifierTestsPath = directory $env:temp/verifier/pester
|
169
144
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
if (test-path $path) {(resolve-path $path).providerpath}
|
174
|
-
else {(resolve-path (mkdir $path)).providerpath}
|
175
|
-
}
|
176
|
-
$VerifierModulePath = directory $env:temp/verifier/modules
|
177
|
-
$VerifierTestsPath = directory $env:temp/verifier/pester
|
178
|
-
|
179
|
-
function test-module($module){
|
180
|
-
(get-module $module -list) -ne $null
|
181
|
-
}
|
182
|
-
if (-not (test-module pester)) {
|
183
|
-
if (test-module PowerShellGet){
|
184
|
-
import-module PowerShellGet -force
|
185
|
-
import-module PackageManagement -force
|
186
|
-
get-packageprovider -name NuGet -force | out-null
|
187
|
-
install-module Pester -force
|
145
|
+
$env:psmodulepath += ";$VerifierModulePath"
|
146
|
+
function test-module($module){
|
147
|
+
(get-module $module -list) -ne $null
|
188
148
|
}
|
189
|
-
|
190
|
-
if (
|
191
|
-
|
149
|
+
if (-not (test-module pester)) {
|
150
|
+
if (test-module PowerShellGet){
|
151
|
+
import-module PowerShellGet -force
|
152
|
+
import-module PackageManagement -force
|
153
|
+
get-packageprovider -name NuGet -force | out-null
|
154
|
+
install-module Pester -force
|
192
155
|
}
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
156
|
+
else {
|
157
|
+
if (-not (test-module PsGet)){
|
158
|
+
$wc = New-Object -TypeName Net.WebClient
|
159
|
+
|
160
|
+
if($env:http_Proxy){
|
161
|
+
if($env:no_proxy){
|
162
|
+
Write-Output "Creating WebProxy with 'http_proxy' and 'no_proxy' environment variables.
|
163
|
+
$webproxy = New-Object System.Net.WebProxy($env:http_Proxy,$true,$env:no_proxy)
|
164
|
+
}else{
|
165
|
+
Write-Output "Creating WebProxy with 'http_proxy' environment variable.
|
166
|
+
$webproxy = New-Object -TypeName System.Net.WebProxy -ArgumentList ($env:http_Proxy)
|
167
|
+
}
|
168
|
+
|
169
|
+
$wc.proxy = $webproxy
|
170
|
+
}
|
171
|
+
|
172
|
+
Invoke-Expression -Command $wc.DownloadString('http://bit.ly/GetPsGet')
|
173
|
+
}
|
174
|
+
try {
|
175
|
+
import-module psget -force -erroraction stop
|
176
|
+
Install-Module Pester
|
177
|
+
}
|
178
|
+
catch {
|
179
|
+
Write-Output "Installing from Github"
|
180
|
+
$zipfile = join-path(resolve-path "$env:temp/verifier") "pester.zip"
|
181
|
+
if (-not (test-path $zipfile)){
|
182
|
+
$source = 'https://github.com/pester/Pester/archive/3.3.14.zip'
|
183
|
+
$wc = New-Object -TypeName Net.WebClient
|
184
|
+
|
185
|
+
if($env:http_Proxy){
|
186
|
+
if($env:no_proxy){
|
187
|
+
Write-Output "Creating WebProxy with 'http_proxy' and 'no_proxy' environment variables."
|
188
|
+
$webproxy = New-Object System.Net.WebProxy($env:http_Proxy,$true,$env:no_proxy)
|
189
|
+
}else{
|
190
|
+
Write-Output "Creating WebProxy with 'http_proxy' environment variable."
|
191
|
+
$webproxy = New-Object -TypeName System.Net.WebProxy -ArgumentList ($env:http_Proxy)
|
192
|
+
}
|
193
|
+
|
194
|
+
$wc.proxy = $webproxy
|
195
|
+
}
|
196
|
+
|
197
|
+
[byte[]]$bytes = $wc.DownloadData($source)
|
198
|
+
[IO.File]::WriteAllBytes($zipfile, $bytes)
|
199
|
+
$bytes = $null
|
200
|
+
[gc]::collect()
|
201
|
+
write-output "Downloaded Pester.zip"
|
202
|
+
}
|
203
|
+
write-output "Creating Shell.Application COM object"
|
204
|
+
$shellcom = new-object -com shell.application
|
205
|
+
Write-Output "Creating COM object for zip file."
|
206
|
+
$zipcomobject = $shellcom.namespace($zipfile)
|
207
|
+
Write-Output "Creating COM object for module destination."
|
208
|
+
$destination = $shellcom.namespace($VerifierModulePath)
|
209
|
+
Write-Output "Unpacking zip file."
|
210
|
+
$destination.CopyHere($zipcomobject.Items(), 0x610)
|
211
|
+
rename-item (join-path $VerifierModulePath "Pester-3.3.14") -newname 'Pester' -force
|
207
212
|
}
|
208
|
-
write-output "Creating Shell.Application COM object"
|
209
|
-
$shellcom = new-object -com shell.application
|
210
|
-
Write-Output "Creating COM object for zip file."
|
211
|
-
$zipcomobject = $shellcom.namespace($zipfile)
|
212
|
-
Write-Output "Creating COM object for module destination."
|
213
|
-
$destination = $shellcom.namespace($VerifierModulePath)
|
214
|
-
Write-Output "Unpacking zip file."
|
215
|
-
$destination.CopyHere($zipcomobject.Items(), 0x610)
|
216
|
-
rename-item (join-path $VerifierModulePath "Pester-3.3.14") -newname 'Pester' -force
|
217
213
|
}
|
218
214
|
}
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
EOH
|
215
|
+
if (-not (test-module Pester)) {
|
216
|
+
throw "Unable to install Pester. Please include Pester in your base image or install during your converge."
|
217
|
+
}
|
218
|
+
EOH
|
224
219
|
end
|
225
220
|
|
226
221
|
def restart_winrm_service
|
@@ -263,7 +258,32 @@ module Kitchen
|
|
263
258
|
end
|
264
259
|
|
265
260
|
def sandboxify_path(path)
|
266
|
-
File.join(sandbox_path, path.sub(
|
261
|
+
File.join(sandbox_path, path.sub(/#{suite_test_folder}\//i, ""))
|
262
|
+
end
|
263
|
+
|
264
|
+
# Returns an Array of common helper filenames currently residing on the
|
265
|
+
# local workstation.
|
266
|
+
#
|
267
|
+
# @return [Array<String>] array of helper files
|
268
|
+
# @api private
|
269
|
+
def helper_files
|
270
|
+
glob = Dir.glob(File.join(test_folder, "helpers", "*/**/*"))
|
271
|
+
glob.reject { |f| File.directory?(f) }
|
272
|
+
end
|
273
|
+
|
274
|
+
# Copies all common testing helper files into the suites directory in
|
275
|
+
# the sandbox.
|
276
|
+
#
|
277
|
+
# @api private
|
278
|
+
def prepare_helpers
|
279
|
+
base = File.join(test_folder, "helpers")
|
280
|
+
|
281
|
+
helper_files.each do |src|
|
282
|
+
dest = File.join(sandbox_path, src.sub("#{base}/", ""))
|
283
|
+
debug("Copying #{src} to #{dest}")
|
284
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
285
|
+
FileUtils.cp(src, dest, preserve: true)
|
286
|
+
end
|
267
287
|
end
|
268
288
|
|
269
289
|
# Copies all test suite files into the suites directory in the sandbox.
|
@@ -282,12 +302,16 @@ module Kitchen
|
|
282
302
|
|
283
303
|
def prepare_powershell_module(name)
|
284
304
|
FileUtils.mkdir_p(File.join(sandbox_path, "modules/#{name}"))
|
285
|
-
FileUtils.cp(
|
305
|
+
FileUtils.cp(
|
306
|
+
File.join(File.dirname(__FILE__), "../../support/powershell/#{name}/#{name}.psm1"),
|
307
|
+
File.join(sandbox_path, "modules/#{name}/#{name}.psm1"),
|
308
|
+
preserve: true
|
309
|
+
)
|
286
310
|
end
|
287
311
|
|
288
312
|
def prepare_powershell_modules
|
289
313
|
info("Preparing to copy supporting powershell modules.")
|
290
|
-
%w[
|
314
|
+
%w[PesterUtil].each do |module_name|
|
291
315
|
prepare_powershell_module module_name
|
292
316
|
end
|
293
317
|
|
data/provision.ps1
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Set-Content -Path "$env:Temp\test.txt" -Value 'testing'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative '..\..\lib\kitchen\verifier\Pester'
|
2
|
+
|
3
|
+
class MockPester < Kitchen::Verifier::Pester
|
4
|
+
def sandbox_path
|
5
|
+
'C:/users/jdoe/temp/kitchen-temp'
|
6
|
+
end
|
7
|
+
def suite_test_folder
|
8
|
+
'C:/lowercasedpath/Pester/tests'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'when sandboxifying a path' do
|
13
|
+
let(:sandboxifiedPath) {
|
14
|
+
pester = MockPester.new
|
15
|
+
pester.sandboxify_path('C:/LOWERcasedpath/Pester/tests/test')
|
16
|
+
}
|
17
|
+
|
18
|
+
it 'should ignore case' do
|
19
|
+
expect(sandboxifiedPath).to eq 'C:/users/jdoe/temp/kitchen-temp/test'
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kitchen-pester
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steven Murawski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-06-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '11.3'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '11.3'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: pry
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '1.
|
61
|
+
version: '1.10'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '1.
|
68
|
+
version: '1.10'
|
69
69
|
description: Skip all that Busser stuff and jump right into Pester.
|
70
70
|
email:
|
71
71
|
- steven.murawski@gmail.com
|
@@ -74,16 +74,20 @@ extensions: []
|
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
76
|
- ".gitignore"
|
77
|
+
- ".kitchen.appveyor.yml"
|
78
|
+
- ".kitchen.yml"
|
77
79
|
- Gemfile
|
78
80
|
- LICENSE
|
79
81
|
- README.md
|
80
82
|
- Rakefile
|
83
|
+
- appveyor.yml
|
81
84
|
- kitchen-pester.gemspec
|
82
85
|
- lib/kitchen/verifier/pester.rb
|
83
86
|
- lib/kitchen/verifier/pester_version.rb
|
84
|
-
- lib/support/powershell/NamedPipes/NamedPipes.psm1
|
85
87
|
- lib/support/powershell/PesterUtil/PesterUtil.psm1
|
86
|
-
-
|
88
|
+
- provision.ps1
|
89
|
+
- spec/pester/pester_spec.rb
|
90
|
+
- test/integration/default/pester/default.tests.ps1
|
87
91
|
homepage: https://github.com/test-kitchen/kitchen-pester
|
88
92
|
licenses:
|
89
93
|
- Apache 2
|
@@ -104,9 +108,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
108
|
version: '0'
|
105
109
|
requirements: []
|
106
110
|
rubyforge_project:
|
107
|
-
rubygems_version: 2.
|
111
|
+
rubygems_version: 2.6.11
|
108
112
|
signing_key:
|
109
113
|
specification_version: 4
|
110
114
|
summary: Test-Kitchen verifier for Pester.
|
111
|
-
test_files:
|
112
|
-
|
115
|
+
test_files:
|
116
|
+
- spec/pester/pester_spec.rb
|
117
|
+
- test/integration/default/pester/default.tests.ps1
|
@@ -1,134 +0,0 @@
|
|
1
|
-
Add-Type -AssemblyName System.Core;
|
2
|
-
|
3
|
-
$script:NamedPipes = @()
|
4
|
-
|
5
|
-
function New-NamedPipe {
|
6
|
-
param (
|
7
|
-
[parameter(Mandatory=$true)]
|
8
|
-
[ValidateSet('In', 'Out')]
|
9
|
-
[string]
|
10
|
-
$Direction,
|
11
|
-
[parameter(Mandatory=$true)]
|
12
|
-
[ValidateSet('Client', 'Server')]
|
13
|
-
[string]
|
14
|
-
$Role,
|
15
|
-
[parameter(Mandatory=$true)]
|
16
|
-
[ValidateNotNullOrEmpty()]
|
17
|
-
[string]
|
18
|
-
$Name,
|
19
|
-
[switch]
|
20
|
-
$Quiet
|
21
|
-
)
|
22
|
-
try {
|
23
|
-
$pipeReader = $null
|
24
|
-
$pipeWriter = $null
|
25
|
-
|
26
|
-
if ($Role -like 'Server') {
|
27
|
-
$pipe = new-object -ErrorAction Stop System.IO.Pipes.NamedPipeServerStream($Name,
|
28
|
-
[System.IO.Pipes.PipeDirection]::$Direction)
|
29
|
-
}
|
30
|
-
else {
|
31
|
-
$pipe = new-object -ErrorAction Stop System.IO.Pipes.NamedPipeClientStream($env:ComputerName,
|
32
|
-
$Name, [System.IO.Pipes.PipeDirection]::$Direction)
|
33
|
-
}
|
34
|
-
if ($Direction -like 'In') {
|
35
|
-
$pipeReader = new-object System.IO.StreamReader($pipe)
|
36
|
-
}
|
37
|
-
else {
|
38
|
-
$pipeWriter = new-object System.IO.StreamWriter($pipe)
|
39
|
-
}
|
40
|
-
$output = new-object PSObject -property @{
|
41
|
-
Name = $Name
|
42
|
-
NamedPipe = $pipe
|
43
|
-
Role = $Role
|
44
|
-
Direction = $Direction
|
45
|
-
PipeReader = $pipeReader
|
46
|
-
PipeWriter = $pipeWriter
|
47
|
-
}
|
48
|
-
$script:NamedPipes += $output
|
49
|
-
if (-not $Quiet) {$output}
|
50
|
-
}
|
51
|
-
catch {
|
52
|
-
throw "Failed to create the named pipe."
|
53
|
-
}
|
54
|
-
}
|
55
|
-
|
56
|
-
function Get-NamedPipe {
|
57
|
-
param (
|
58
|
-
$Name = '*',
|
59
|
-
$Role = '*'
|
60
|
-
)
|
61
|
-
$pipe = $null
|
62
|
-
$pipe = $script:NamedPipes |
|
63
|
-
where {$_.name -like $Name -and $_.role -like $Role}
|
64
|
-
if ($pipe -eq $null) { throw "Unable to find pipe $Name" }
|
65
|
-
return $pipe
|
66
|
-
}
|
67
|
-
|
68
|
-
function Start-NamedPipeServer {
|
69
|
-
param ($Name)
|
70
|
-
$PipeServer = Get-NamedPipe -Name $Name -Role Server
|
71
|
-
$PipeServer.NamedPipe.WaitForConnection()
|
72
|
-
Write-Host "Named Pipe $Name is connected."
|
73
|
-
}
|
74
|
-
|
75
|
-
function Connect-NamedPipeClient {
|
76
|
-
param ($Name)
|
77
|
-
$PipeClient = Get-NamedPipe -Name $Name -Role Client
|
78
|
-
$PipeClient.NamedPipe.Connect()
|
79
|
-
if ($PipeClient.PipeWriter -ne $null) {
|
80
|
-
$PipeClient.pipeWriter.AutoFlush = $true
|
81
|
-
}
|
82
|
-
}
|
83
|
-
|
84
|
-
function Write-NamedPipe {
|
85
|
-
param(
|
86
|
-
[parameter(Mandatory = $true)]
|
87
|
-
[ValidateNotNullOrEmpty()]
|
88
|
-
[string]
|
89
|
-
$Name,
|
90
|
-
[parameter(ValueFromPipeline=$true)]
|
91
|
-
[string]
|
92
|
-
$Content)
|
93
|
-
begin {
|
94
|
-
$Pipe = Get-NamedPipe -Name $Name |
|
95
|
-
where {$_.PipeWriter -ne $null}
|
96
|
-
}
|
97
|
-
process {
|
98
|
-
if ($Pipe.NamedPipe.IsConnected){
|
99
|
-
$Pipe.PipeWriter.Writeline($Content)
|
100
|
-
}
|
101
|
-
}
|
102
|
-
}
|
103
|
-
|
104
|
-
function Read-NamedPipe {
|
105
|
-
param ($Name)
|
106
|
-
$Pipe = Get-NamedPipe -Name $Name | where {$_.PipeReader -ne $null}
|
107
|
-
while ($Pipe.NamedPipe.IsConnected) {
|
108
|
-
$output = $Pipe.PipeReader.ReadLine()
|
109
|
-
if ($output -like "STOP READING $Name") {
|
110
|
-
break;
|
111
|
-
}
|
112
|
-
$output
|
113
|
-
}
|
114
|
-
}
|
115
|
-
|
116
|
-
function Send-StopReadingCommand {
|
117
|
-
param ($Name)
|
118
|
-
Write-NamedPipe -Name $Name -Content "STOP READING $Name"
|
119
|
-
}
|
120
|
-
|
121
|
-
function Remove-NamedPipe {
|
122
|
-
param ($name)
|
123
|
-
Get-NamedPipe -Name $Name |
|
124
|
-
foreach {
|
125
|
-
if ($_.Pipewriter -ne $null) {
|
126
|
-
$_.PipeWriter.dispose()
|
127
|
-
}
|
128
|
-
if ($_.Pipereader -ne $null) {
|
129
|
-
$_.Pipereader.dispose()
|
130
|
-
}
|
131
|
-
$_.NamedPipe.dispose()
|
132
|
-
}
|
133
|
-
$script:NamedPipes = $script:NamedPipes | where {$_.name -notlike $Name}
|
134
|
-
}
|
@@ -1,92 +0,0 @@
|
|
1
|
-
import-module NamedPipes -force
|
2
|
-
|
3
|
-
$script:TaskLastExitCode = @{}
|
4
|
-
|
5
|
-
function Add-ScheduledTaskCommand {
|
6
|
-
param ([string]$Name, [scriptblock]$Action)
|
7
|
-
$command = @"
|
8
|
-
`$env:temp = '$env:temp';
|
9
|
-
`$env:psmodulepath = '$env:psmodulepath';
|
10
|
-
import-module NamedPipes -force;
|
11
|
-
|
12
|
-
# Set up named pipe
|
13
|
-
start-sleep -seconds 5
|
14
|
-
|
15
|
-
New-NamedPipe -Role Client -Direction Out -Quiet -Name 'kitchen-$name';
|
16
|
-
Connect-NamedPipeClient -Name 'kitchen-$name';
|
17
|
-
|
18
|
-
# Run the real action and send it down the named pipe
|
19
|
-
try {
|
20
|
-
`$ActionString = @'
|
21
|
-
$($action.ToString())
|
22
|
-
'@
|
23
|
-
|
24
|
-
[scriptblock]::create(`$ActionString).InvokeReturnAsIs() |
|
25
|
-
write-NamedPipe -Name 'kitchen-$name'
|
26
|
-
}
|
27
|
-
catch [Exception] {
|
28
|
-
write-NamedPipe -name 'kitchen-$name' -content `$_.exception.message
|
29
|
-
Write-NamedPipe -Name 'kitchen-$name' -content `$_.exception.stacktrace
|
30
|
-
}
|
31
|
-
finally {
|
32
|
-
# Close out named pipe
|
33
|
-
Send-StopReadingCommand -Name 'kitchen-$name';
|
34
|
-
Remove-NamedPipe -Name 'kitchen-$name';
|
35
|
-
}
|
36
|
-
"@
|
37
|
-
|
38
|
-
try {
|
39
|
-
$ActionWithEnvironment = [scriptblock]::Create($command)
|
40
|
-
}
|
41
|
-
catch {
|
42
|
-
Write-Output "Failed to validate: "
|
43
|
-
Write-Output $command
|
44
|
-
throw $_.exception
|
45
|
-
}
|
46
|
-
|
47
|
-
$ActionWithEnvironment.ToString() | Out-file "$env:temp/$Name.ps1"
|
48
|
-
if (test-path "$env:temp/$name.ps1") {
|
49
|
-
schtasks /create /tn "kitchen-$name" /ru System /sc daily /st 00:00 /rl HIGHEST /f /tr "powershell -noprofile -executionpolicy unrestricted -file $env:temp/$name.ps1" | Out-Null
|
50
|
-
Write-Host "`tCreated Scheduled Task $Name."
|
51
|
-
}
|
52
|
-
else {
|
53
|
-
throw "failed to create scheduled task command."
|
54
|
-
}
|
55
|
-
}
|
56
|
-
|
57
|
-
function Remove-ScheduledTaskCommand {
|
58
|
-
param ([string]$Name)
|
59
|
-
schtasks /delete /tn "kitchen-$name" /f | Out-Null
|
60
|
-
Write-Host "`tDeleted Scheduld Task $Name."
|
61
|
-
}
|
62
|
-
|
63
|
-
function Get-ScheduledTaskExitCode {
|
64
|
-
param ([string]$Name)
|
65
|
-
(Get-ScheduledTaskStatus -name $name).'Last Result' |
|
66
|
-
where {-not [string]::IsNullOrEmpty($_)} |
|
67
|
-
foreach {[int]::Parse($_.trim())}
|
68
|
-
}
|
69
|
-
|
70
|
-
function Get-ScheduledTaskStatus {
|
71
|
-
param ([string]$Name)
|
72
|
-
$task = schtasks /query /tn "kitchen-$name" /fo csv /v |
|
73
|
-
ConvertFrom-Csv
|
74
|
-
$task
|
75
|
-
}
|
76
|
-
|
77
|
-
function Invoke-ScheduledTaskCommand {
|
78
|
-
param ([string]$Name)
|
79
|
-
try {
|
80
|
-
new-namedpipe -Role Server -Direction In -Quiet -Name "kitchen-$name"
|
81
|
-
schtasks /run /tn "kitchen-$name" | Out-Null
|
82
|
-
Write-Host "`tRunning Scheduled Task $Name."
|
83
|
-
Start-NamedPipeServer -Name "kitchen-$name"
|
84
|
-
Read-NamedPipe -Name "kitchen-$name"
|
85
|
-
}
|
86
|
-
finally {
|
87
|
-
Remove-NamedPipe -name "kitchen-$name"
|
88
|
-
while ((Get-ScheduledTaskStatus -name $name).Status -notlike 'Ready') {
|
89
|
-
start-sleep -seconds 1
|
90
|
-
}
|
91
|
-
}
|
92
|
-
}
|