Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit90b4e2a

Browse files
authored
Merge pull request#937 from SteveL-MSFT/psscript
PSScript resource
2 parentsc1b98e1 +869d9fb commit90b4e2a

File tree

7 files changed

+703
-1
lines changed

7 files changed

+703
-1
lines changed

‎build.ps1

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ $filesForWindowsPackage = @(
5353
'osinfo.dsc.resource.json',
5454
'powershell.dsc.resource.json',
5555
'psDscAdapter/',
56+
'psscript.ps1',
57+
'psscript.dsc.resource.json',
58+
'winpsscript.dsc.resource.json',
5659
'reboot_pending.dsc.resource.json',
5760
'reboot_pending.resource.ps1',
5861
'registry.dsc.resource.json',
@@ -87,6 +90,8 @@ $filesForLinuxPackage = @(
8790
'osinfo.dsc.resource.json',
8891
'powershell.dsc.resource.json',
8992
'psDscAdapter/',
93+
'psscript.ps1',
94+
'psscript.dsc.resource.json',
9095
'RunCommandOnSet.dsc.resource.json',
9196
'runcommandonset',
9297
'sshdconfig',
@@ -109,6 +114,8 @@ $filesForMacPackage = @(
109114
'osinfo.dsc.resource.json',
110115
'powershell.dsc.resource.json',
111116
'psDscAdapter/',
117+
'psscript.ps1',
118+
'psscript.dsc.resource.json',
112119
'RunCommandOnSet.dsc.resource.json',
113120
'runcommandonset',
114121
'sshdconfig',
@@ -300,6 +307,7 @@ if (!$SkipBuild) {
300307
"dscecho",
301308
"osinfo",
302309
"powershell-adapter",
310+
'resources/PSScript',
303311
"process",
304312
"runcommandonset",
305313
"sshdconfig",
@@ -422,7 +430,8 @@ if (!$SkipBuild) {
422430
Copy-Item"*.dsc.resource.json"$target-Force-ErrorAction Ignore
423431
}
424432
else {# don't copy WindowsPowerShell resource manifest
425-
Copy-Item"*.dsc.resource.json"$target-Exclude'windowspowershell.dsc.resource.json'-Force-ErrorAction Ignore
433+
$exclude=@('windowspowershell.dsc.resource.json','winpsscript.dsc.resource.json')
434+
Copy-Item"*.dsc.resource.json"$target-Exclude$exclude-Force-ErrorAction Ignore
426435
}
427436

428437
# be sure that the files that should be executable are executable

‎dsc/examples/psscript.dsc.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Example configuration using PowerShell script resource and using parameters and input
2+
$schema:https://aka.ms/dsc/schemas/v3/bundled/config/document.json
3+
parameters:
4+
myName:
5+
type:string
6+
defaultValue:Steve
7+
myObject:
8+
type:object
9+
defaultValue:
10+
color:green
11+
number:10
12+
resources:
13+
-name:Use PS script
14+
type:Microsoft.DSC.Transitional/PowerShellScript
15+
properties:
16+
input:
17+
-name:"[parameters('myName')]"
18+
-object:"[parameters('myObject')]"
19+
getScript:|
20+
param($inputArray)
21+
22+
Write-Warning "This is a warning message"
23+
# any output will be collected and returned
24+
"My name is " + $inputArray[0].name
25+
"My color is " + $inputArray[1].object.color

‎resources/PSScript/copy_files.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
./psscript.ps1
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
{
2+
"$schema":"https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
3+
"type":"Microsoft.DSC.Transitional/PowerShellScript",
4+
"description":"Enable running PowerShell 7 scripts inline",
5+
"version":"0.1.0",
6+
"get": {
7+
"executable":"pwsh",
8+
"args": [
9+
"-NoLogo",
10+
"-NonInteractive",
11+
"-NoProfile",
12+
"-ExecutionPolicy",
13+
"Bypass",
14+
"-Command",
15+
"$input | ./psscript.ps1",
16+
"get"
17+
],
18+
"input":"stdin"
19+
},
20+
"set": {
21+
"executable":"pwsh",
22+
"args": [
23+
"-NoLogo",
24+
"-NonInteractive",
25+
"-NoProfile",
26+
"-ExecutionPolicy",
27+
"Bypass",
28+
"-Command",
29+
"$input | ./psscript.ps1",
30+
"set"
31+
],
32+
"implementsPretest":true,
33+
"input":"stdin",
34+
"return":"state"
35+
},
36+
"test": {
37+
"executable":"pwsh",
38+
"args": [
39+
"-NoLogo",
40+
"-NonInteractive",
41+
"-NoProfile",
42+
"-ExecutionPolicy",
43+
"Bypass",
44+
"-Command",
45+
"$input | ./psscript.ps1",
46+
"test"
47+
],
48+
"input":"stdin",
49+
"return":"state"
50+
},
51+
"exitCodes": {
52+
"0":"Success",
53+
"1":"PowerShell script execution failed",
54+
"2":"PowerShell exception occurred",
55+
"3":"Script had errors"
56+
},
57+
"schema": {
58+
"embedded": {
59+
"type":"object",
60+
"properties": {
61+
"getScript": {
62+
"type": ["string","null"]
63+
},
64+
"setScript": {
65+
"type": ["string","null"]
66+
},
67+
"testScript": {
68+
"type": ["string","null"]
69+
},
70+
"input": {
71+
"type": ["string","boolean","integer","object","array","null"]
72+
},
73+
"output": {
74+
"type": ["array","null"]
75+
},
76+
"_inDesiredState": {
77+
"type": ["boolean","null"],
78+
"default":null
79+
}
80+
}
81+
}
82+
}
83+
}

‎resources/PSScript/psscript.ps1

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
[CmdletBinding()]
4+
param(
5+
[Parameter(Mandatory=$true,Position=0)]
6+
[ValidateSet('Get','Set','Test')]
7+
[string]$Operation,
8+
[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$true)]
9+
[string]$jsonInput
10+
)
11+
12+
functionWrite-DscTrace {
13+
param(
14+
[Parameter(Mandatory=$true)]
15+
[ValidateSet('Error','Warn','Info','Debug','Trace')]
16+
[string]$Level,
17+
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
18+
[string]$Message,
19+
[switch]$Now
20+
)
21+
22+
$trace=@{$Level.ToLower()=$Message }|ConvertTo-Json-Compress
23+
24+
if ($Now) {
25+
$host.ui.WriteErrorLine($trace)
26+
}else {
27+
$traceQueue.Enqueue($trace)
28+
}
29+
}
30+
31+
$scriptObject=$jsonInput|ConvertFrom-Json
32+
33+
$script=switch ($Operation) {
34+
'Get' {
35+
$scriptObject.GetScript
36+
}
37+
'Set' {
38+
$scriptObject.SetScript
39+
}
40+
'Test' {
41+
$scriptObject.TestScript
42+
}
43+
}
44+
45+
if ($null-eq$script) {
46+
Write-DscTrace-Now-Level Info-Message"No script found for operation '$Operation'."
47+
if ($Operation-eq'Test') {
48+
# if not implemented, we return it's in desired state
49+
@{_inDesiredState=$true }|ConvertTo-Json-Compress
50+
exit0
51+
}
52+
53+
# write an empty json object to stdout
54+
'{}'
55+
exit0
56+
}
57+
58+
# use AST to see if script has param block, if any errors exit with error message
59+
$errors=$null
60+
$tokens=$null
61+
$ast= [System.Management.Automation.Language.Parser]::ParseInput($script, [ref]$tokens, [ref]$errors)
62+
if ($errors.Count-gt0) {
63+
$errorMessage=$errors|ForEach-Object {$_.ToString() }
64+
Write-DscTrace-Now-Level Error-Message"Script has syntax errors:$errorMessage"
65+
exit3
66+
}
67+
68+
$paramName=if ($null-ne$ast.ParamBlock) {
69+
# make sure it only specifies one parameter and get the name of that parameter
70+
if ($ast.ParamBlock.Parameters.Count-ne1) {
71+
Write-DscTrace-Now-Level Error-Message'Script must have exactly one parameter.'
72+
exit3
73+
}
74+
$ast.ParamBlock.Parameters[0].Name.VariablePath.UserPath
75+
}else {
76+
$null
77+
}
78+
79+
$ps= [PowerShell]::Create().AddScript({
80+
$DebugPreference='Continue'
81+
$VerbosePreference='Continue'
82+
$ErrorActionPreference='Stop'
83+
}).AddStatement().AddScript($script)
84+
85+
if ($null-ne$scriptObject.input) {
86+
if ($null-eq$paramName) {
87+
Write-DscTrace-Now-Level Error-Message'Input was provided but script does not have a parameter to accept input.'
88+
exit3
89+
}
90+
$null=$ps.AddParameter($paramName,$scriptObject.input)
91+
}elseif ($null-ne$paramName) {
92+
Write-DscTrace-Now-Level Error-Message"Script has a parameter '$paramName' but no input was provided."
93+
exit3
94+
}
95+
96+
$traceQueue= [System.Collections.Concurrent.ConcurrentQueue[object]]::new()
97+
98+
$null=Register-ObjectEvent-InputObject$ps.Streams.Error-EventName DataAdding-MessageData$traceQueue-Action {
99+
$traceQueue=$Event.MessageData
100+
# convert error to string since it's an ErrorRecord
101+
$traceQueue.Enqueue((@{error= [string]$EventArgs.ItemAdded }|ConvertTo-Json-Compress))
102+
}
103+
$null=Register-ObjectEvent-InputObject$ps.Streams.Warning-EventName DataAdding-MessageData$traceQueue-Action {
104+
$traceQueue=$Event.MessageData
105+
$traceQueue.Enqueue((@{warn=$EventArgs.ItemAdded.Message }|ConvertTo-Json-Compress))
106+
}
107+
$null=Register-ObjectEvent-InputObject$ps.Streams.Information-EventName DataAdding-MessageData$traceQueue-Action {
108+
$traceQueue=$Event.MessageData
109+
if ($null-ne$EventArgs.ItemAdded.MessageData) {
110+
if ($EventArgs.ItemAdded.Tags-contains'PSHOST') {
111+
$traceQueue.Enqueue((@{info=$EventArgs.ItemAdded.MessageData.ToString() }|ConvertTo-Json-Compress))
112+
}else {
113+
$traceQueue.Enqueue((@{trace=$EventArgs.ItemAdded.MessageData.ToString() }|ConvertTo-Json-Compress))
114+
}
115+
return
116+
}
117+
}
118+
$null=Register-ObjectEvent-InputObject$ps.Streams.Verbose-EventName DataAdding-MessageData$traceQueue-Action {
119+
$traceQueue=$Event.MessageData
120+
$traceQueue.Enqueue((@{info=$EventArgs.ItemAdded.Message }|ConvertTo-Json-Compress))
121+
}
122+
$null=Register-ObjectEvent-InputObject$ps.Streams.Debug-EventName DataAdding-MessageData$traceQueue-Action {
123+
$traceQueue=$Event.MessageData
124+
$traceQueue.Enqueue((@{debug=$EventArgs.ItemAdded.Message }|ConvertTo-Json-Compress))
125+
}
126+
$outputObjects= [System.Collections.Generic.List[Object]]::new()
127+
128+
functionWrite-TraceQueue() {
129+
$trace=$null
130+
while (!$traceQueue.IsEmpty) {
131+
if ($traceQueue.TryDequeue([ref]$trace)) {
132+
$host.ui.WriteErrorLine($trace)
133+
}
134+
}
135+
}
136+
137+
try {
138+
$asyncResult=$ps.BeginInvoke()
139+
while (-not$asyncResult.IsCompleted) {
140+
Write-TraceQueue
141+
142+
Start-Sleep-Milliseconds100
143+
}
144+
$outputCollection=$ps.EndInvoke($asyncResult)
145+
Write-TraceQueue
146+
147+
148+
if ($ps.HadErrors) {
149+
# If there are any errors, we will exit with an error code
150+
Write-DscTrace-Now-Level Error-Message'Errors occurred during script execution.'
151+
exit1
152+
}
153+
154+
foreach ($outputin$outputCollection) {
155+
$outputObjects.Add($output)
156+
}
157+
}
158+
catch {
159+
Write-DscTrace-Now-Level Error-Message$_
160+
exit1
161+
}
162+
finally {
163+
$ps.Dispose()
164+
Get-EventSubscriber|Unregister-Event
165+
}
166+
167+
# Test should return a single boolean value indicating if in the desired state
168+
if ($Operation-eq'Test') {
169+
if ($outputObjects.Count-eq1-and$outputObjects[0]-is [bool]) {
170+
@{_inDesiredState=$outputObjects[0] }|ConvertTo-Json-Compress
171+
}else {
172+
Write-DscTrace-Now-Level Error-Message'Test operation did not return a single boolean value.'
173+
exit1
174+
}
175+
}else {
176+
@{output=$outputObjects }|ConvertTo-Json-Compress-Depth10
177+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp