Skip to content

Commit 0e17d9f

Browse files
see changelog for v0.5.0
1 parent 6c274a8 commit 0e17d9f

9 files changed

+184
-70
lines changed

PSRemoteOperations.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
RootModule = 'PSRemoteOperations.psm1'
99

1010
# Version number of this module.
11-
ModuleVersion = '0.4.0'
11+
ModuleVersion = '0.5.0'
1212

1313
# Supported PSEditions
1414
CompatiblePSEditions = @("Desktop")

PSRemoteOperations.psm1

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Function New-PSRemoteOperation {
1414
HelpMessage = "Enter the name of the computer where this command will execute.")]
1515
[Alias("CN")]
1616
[ValidateNotNullorEmpty()]
17-
[string]$Computername,
17+
[string[]]$Computername,
1818

1919
[Parameter(
2020
Mandatory,
@@ -47,19 +47,42 @@ Function New-PSRemoteOperation {
4747

4848
Write-Verbose "Starting $($MyInvocation.MyCommand)"
4949

50+
foreach ($Computer in $Computername) {
51+
Write-Verbose "Creating a remote operations file for $($computer.toUpper())"
5052
#define a here string for the psd1 content
5153
$out = @"
5254
@{
5355
CreatedOn = '$($env:computername)'
5456
CreatedBy = '$($env:userdomain)\$($env:username)'
5557
CreatedAt = '$((Get-Date).toUniversalTime()) UTC'
56-
Computername = '$Computername'
58+
Computername = '$($Computer.ToUpper())'
5759
5860
"@
5961

6062
if ($ArgumentList) {
61-
$args = "$($ArgumentList -join ",")"
62-
$out += "ArgumentList = '$args'"
63+
$outargs = @()
64+
foreach ($a in $ArgumentList ) {
65+
66+
Switch ($a.gettype().name) {
67+
"Object[]" {
68+
$items = "'$($a -join "','")'"
69+
$thisarg = "@($items)"
70+
}
71+
"Boolean" {
72+
$thisarg = "`$$($a)"
73+
}
74+
"string" {
75+
$thisarg = "'$a'"
76+
}
77+
Default {
78+
$thisarg = $a
79+
}
80+
}
81+
$outargs+=$thisarg
82+
}
83+
84+
$opargs = $outargs -join ","
85+
$out += "ArgumentList = $opargs"
6386
$out += "`n"
6487
}
6588

@@ -81,15 +104,17 @@ Computername = '$Computername'
81104
$out | Write-Verbose
82105

83106
#make the filename all lower case
84-
$fname = "$($Computername)_$(New-GUID).psd1"
85-
$outFile = Join-path -Path $Path -ChildPath $fname.toLower()
107+
$fname = "$($Computer.ToUpper())_$(New-GUID).psd1"
108+
$outFile = Join-path -Path $Path -ChildPath $fname #.toLower()
86109

87110
Write-Verbose "Creating datafile $outfile"
88111

89-
$out | Out-File -FilePath $outFile -force
112+
$out | Out-File -FilePath $outFile -force -Encoding ascii
90113
if ($Passthru) {
91114
Get-Item -path $outFile
92115
}
116+
} #foreach computer
117+
93118
Write-Verbose "Ending $($MyInvocation.MyCommand)"
94119
} #close New-PSRemoteOperation
95120

@@ -145,8 +170,9 @@ Function Invoke-PSRemoteOperation {
145170
if ($in.Scriptblock) {
146171
$in.Scriptblock = [scriptblock]::Create($in.Scriptblock)
147172
}
173+
148174
if ($in.ArgumentList) {
149-
$in.ArgumentList = $in.ArgumentList -split ","
175+
$in.ArgumentList = $in.ArgumentList # -split ","
150176
}
151177

152178
#run the command
@@ -202,7 +228,7 @@ Function Invoke-PSRemoteOperation {
202228
$resultFile = Join-Path -Path $ArchivePath -ChildPath $filename
203229

204230
Write-Verbose "Creating results file $resultFile"
205-
$resultdata | Out-File -FilePath $resultFile
231+
$resultdata | Out-File -FilePath $resultFile -Encoding ascii
206232

207233
#delete
208234
Write-Verbose "Removing operation file $cPath"
@@ -249,7 +275,7 @@ Function Get-PSRemoteOperationResult {
249275
$data = $data | Select-object -First $Newest
250276
}
251277
foreach ($file in $data) {
252-
write-verbose "Processing $($file.fullname)"
278+
Write-Verbose "Processing $($file.fullname)"
253279
$hash = Import-PowerShellDataFile -Path $file.fullname
254280
$hash.Add("Path", $file.fullname)
255281
$obj = New-Object -typename psobject -Property $hash

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ Or check out the individual commands:
1111
+ [New-PSRemoteOperation](docs/New-PSRemoteOperation.md)
1212
+ [Register-PSRemoteOperationWatcher](docs/Register-PSRemoteOperationWatcher.md)
1313

14-
*last updated 2 October 2018*
14+
*last updated 4 October 2018*

changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog for PSRemoteOperations
22

3+
## v0.5.0
4+
5+
+ Modified `-Computername` parameter on `New-PSRemoteOperation` to accept an array of names. (Issue #1)
6+
+ Set file encoding of psd1 files to ASCII (Issue #4)
7+
+ Fixed bug with arguments when one of them is an array. (Issue #5)
8+
39
## v0.4.0
410

511
+ Added initialization script option to RemoteJob definition and execution

docs/New-PSRemoteOperation.md

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ Create a new remote operation file.
1616
### scriptblock (Default)
1717

1818
```yaml
19-
New-PSRemoteOperation [-Computername] <String> -Scriptblock <ScriptBlock> [-ArgumentList <Object[]>]
19+
New-PSRemoteOperation [-Computername] <String[]> -Scriptblock <ScriptBlock> [-ArgumentList <Object[]>]
2020
[-Initialization <ScriptBlock>] [-Path <String>] [-Passthru] [<CommonParameters>]
2121
```
2222

2323
### filepath
2424

2525
```yaml
26-
New-PSRemoteOperation [-Computername] <String> -ScriptPath <String> [-ArgumentList <Object[]>]
26+
New-PSRemoteOperation [-Computername] <String[]> -ScriptPath <String> [-ArgumentList <Object[]>]
2727
[-Initialization <ScriptBlock>] [-Path <String>] [-Passthru] [<CommonParameters>]
2828
```
2929

@@ -57,6 +57,29 @@ Mode LastWriteTime Length Name
5757

5858
Repeat the previous example but create the file in a UNC path and pass the file object to the pipeline.
5959

60+
### Example 3
61+
62+
```powershell
63+
PS C:\> $computers = Get-Content computers.txt
64+
PS C:\> New-PSRemoteOperation -Computername $computers -Scriptblock {
65+
if (-Not (Test-Path C:\Work)) {
66+
mkdir c:\work
67+
}
68+
Copy-Item C:\Data\foo.dat -destination C:\work
69+
}
70+
```
71+
72+
In this example, an array of computer names is taken from the text file. A PSRemoteOperation file will be created for each computer using the same scriptblock.
73+
74+
### Example 4
75+
76+
```powershell
77+
PS C:\> $sb = {param([string[]]$Names,[string]$Path,[boolean]$append) restart-service $names -force -PassThru | out-file $path -append:$append -encoding ascii
78+
}
79+
PS C:\> New-PSRemoteOperation -Computername SRV4 -Scriptblock $sb -ArgumentList @("spooler","bits"),"c:\work\svc.txt",$True
80+
81+
```
82+
6083
## PARAMETERS
6184

6285
### -ArgumentList
@@ -77,10 +100,10 @@ Accept wildcard characters: False
77100
78101
### -Computername
79102
80-
Enter the name of the computer where this command will execute.
103+
Enter the name or names of the computer where this command will execute.
81104
82105
```yaml
83-
Type: String
106+
Type: String[]
84107
Parameter Sets: (All)
85108
Aliases: CN
86109

@@ -172,9 +195,7 @@ Accept wildcard characters: False
172195
```
173196
174197
### CommonParameters
175-
176-
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable.
177-
For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
198+
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
178199
179200
## INPUTS
180201

docs/about_PSRemoteOperations.md

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# PSRemoteOperation
22

3-
## about_PSRemoteOperation
3+
## about_PSRemoteOperations
44

55
## SHORT DESCRIPTION
66

@@ -30,34 +30,56 @@ It is strongly recommended that you define two global variables in your
3030
PowerShell profile script. The commands in this module are designed to use the
3131
variables as default.
3232

33-
$PSRemoteOpPath will be the path where the PSRemoteOperation files will be
33+
`$PSRemoteOpPath` will be the path where the PSRemoteOperation files will be
3434
created.
3535

36-
$PSRemoteOpArchive will be the path where the archive files will be created.
37-
Typically this will be a subfolder of $PSRemoteOpPath.
36+
`$PSRemoteOpArchive` will be the path where the archive files will be created.
37+
Typically, this will be a sub-folder of `$PSRemoteOpPath`.
3838

39-
PS C:\> mkdir c:\users\jeff\dropbox\ops\archive
40-
PS C:\> $PSRemoteOpPath = "c:\users\jeff\dropbox\ops\"
41-
PS C:\> $PSRemoteOpArchive = "c:\users\jeff\dropbox\ops\archive"
39+
```powershell
40+
PS C:\> mkdir c:\users\jeff\dropbox\ops\archive
41+
PS C:\> $PSRemoteOpPath = "c:\users\jeff\dropbox\ops\"
42+
PS C:\> $PSRemoteOpArchive = "c:\users\jeff\dropbox\ops\archive"
43+
```
4244

4345
## EXAMPLES
4446

4547
With these default variables, here's how you might use the commands in this
4648
module. First, you need to create an operation file.
4749

48-
PS C:\> New-PSRemoteOperation -Computername SRV1 -Scriptblock {restart-service spooler -force}
50+
```powershell
51+
PS C:\> New-PSRemoteOperation -Computername SRV1 -Scriptblock {restart-service spooler -force}
52+
```
4953

5054
This will create a file using the naming convention <computername>_<uid>.psd1.
5155
It is assumed that the destination path, $PSRemoteOpPath, is being replicated
5256
in some way to the remote computer, SRV1.
5357

58+
You can also create multiple remote operations file to run the same script or
59+
scriptblock.
60+
61+
```powershell
62+
PS C:\> $computers = Get-Content computers.txt
63+
PS C:\> New-PSRemoteOperation -Computername $computers -Scriptblock {
64+
if (-Not (Test-Path C:\Work)) {
65+
mkdir c:\work
66+
}
67+
Copy-Item C:\Data\foo.dat -destination C:\work
68+
}
69+
```
70+
71+
This will create multiple psd1 files with the same scriptblock but for each
72+
computer in the $Computers variable.
73+
5474
The remote computer needs some means of monitoring the target folder and
5575
invoking the file when detected. You can use whatever means you want. You may
5676
want to setup a FileWatcher or WMI Event subscription. You may have 3rd party
5777
products you can use. However you monitor the folder, once you've identified a
5878
matching file, use Invoke-PSRemoteOperation to execute it.
5979

60-
PS C:\> Invoke-PSRemoteOperation $file -archivepath c:\archive
80+
```powershell
81+
PS C:\> Invoke-PSRemoteOperation $file -archivepath c:\archive
82+
```
6183

6284
Once the operation is complete, the original file is deleted and an archive
6385
version is created in the archive path location. If you placed your archive
@@ -66,7 +88,8 @@ as a sub-directory, the results will "replicate" back to you.
6688
On your computer, you can use Get-PSRemoteOperationResult to get the results
6789
from one or more computers or operations.
6890

69-
PS C:\> Get-PSRemoteOperationResult -Computername SRV1 -Newest 1
91+
```powershell
92+
PS C:\> Get-PSRemoteOperationResult -Computername SRV1 -Newest 1
7093
7194
Computername : SRV1
7295
Date : 10/02/2018 21:29:35 UTC
@@ -75,6 +98,7 @@ from one or more computers or operations.
7598
ArgumentsList :
7699
Completed : True
77100
Error :
101+
```
78102

79103
In this example, the command is getting new last result for computer SRV1.
80104

@@ -84,12 +108,14 @@ need to.
84108
The module includes a command to setup a default "watcher" using a PowerShell
85109
scheduled job.
86110

87-
PS C:\> Register-PSRemoteOperationWatcher
111+
```powershell
112+
PS C:\> Register-PSRemoteOperationWatcher
113+
```
88114

89115
You will be prompted for your user credentials. This will create a scheduled
90116
job called RemoteOpWatcher that will check every 5 minutes for matching files
91-
in $PSRemoteOpPath and use $PSRemoteOpArchive for the archive path. Use the
92-
scheduled job cmdlets to modify or unregister. Note that the job won't start
117+
in `$PSRemoteOpPath` and use `$PSRemoteOpArchive` for the archive path. Use the
118+
scheduled job cmdlets to modify or un-register. Note that the job won't start
93119
for 2 minutes upon initial setup. But thereafter it will run indefinitely and
94120
survive reboots.
95121

en-us/PSRemoteOperations-help.xml

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -326,11 +326,11 @@ PS C:\&gt; Invoke-PSRemoteOperation $file</dev:code>
326326
<command:parameter required="true" variableLength="true" globbing="false" pipelineInput="False" position="0" aliases="CN">
327327
<maml:name>Computername</maml:name>
328328
<maml:Description>
329-
<maml:para>Enter the name of the computer where this command will execute.</maml:para>
329+
<maml:para>Enter the name or names of the computer where this command will execute.</maml:para>
330330
</maml:Description>
331-
<command:parameterValue required="true" variableLength="false">String</command:parameterValue>
331+
<command:parameterValue required="true" variableLength="false">String[]</command:parameterValue>
332332
<dev:type>
333-
<maml:name>String</maml:name>
333+
<maml:name>String[]</maml:name>
334334
<maml:uri />
335335
</dev:type>
336336
<dev:defaultValue>None</dev:defaultValue>
@@ -400,11 +400,11 @@ PS C:\&gt; Invoke-PSRemoteOperation $file</dev:code>
400400
<command:parameter required="true" variableLength="true" globbing="false" pipelineInput="False" position="0" aliases="CN">
401401
<maml:name>Computername</maml:name>
402402
<maml:Description>
403-
<maml:para>Enter the name of the computer where this command will execute.</maml:para>
403+
<maml:para>Enter the name or names of the computer where this command will execute.</maml:para>
404404
</maml:Description>
405-
<command:parameterValue required="true" variableLength="false">String</command:parameterValue>
405+
<command:parameterValue required="true" variableLength="false">String[]</command:parameterValue>
406406
<dev:type>
407-
<maml:name>String</maml:name>
407+
<maml:name>String[]</maml:name>
408408
<maml:uri />
409409
</dev:type>
410410
<dev:defaultValue>None</dev:defaultValue>
@@ -486,11 +486,11 @@ PS C:\&gt; Invoke-PSRemoteOperation $file</dev:code>
486486
<command:parameter required="true" variableLength="true" globbing="false" pipelineInput="False" position="0" aliases="CN">
487487
<maml:name>Computername</maml:name>
488488
<maml:Description>
489-
<maml:para>Enter the name of the computer where this command will execute.</maml:para>
489+
<maml:para>Enter the name or names of the computer where this command will execute.</maml:para>
490490
</maml:Description>
491-
<command:parameterValue required="true" variableLength="false">String</command:parameterValue>
491+
<command:parameterValue required="true" variableLength="false">String[]</command:parameterValue>
492492
<dev:type>
493-
<maml:name>String</maml:name>
493+
<maml:name>String[]</maml:name>
494494
<maml:uri />
495495
</dev:type>
496496
<dev:defaultValue>None</dev:defaultValue>
@@ -612,6 +612,28 @@ Mode LastWriteTime Length Name
612612
<maml:para>Repeat the previous example but create the file in a UNC path and pass the file object to the pipeline.</maml:para>
613613
</dev:remarks>
614614
</command:example>
615+
<command:example>
616+
<maml:title>-------------------------- Example 3 --------------------------</maml:title>
617+
<dev:code>PS C:\&gt; $computers = Get-Content computers.txt
618+
PS C:\&gt; New-PSRemoteOperation -Computername $computers -Scriptblock {
619+
if (-Not (Test-Path C:\Work)) {
620+
mkdir c:\work
621+
}
622+
Copy-Item C:\Data\foo.dat -destination C:\work
623+
}</dev:code>
624+
<dev:remarks>
625+
<maml:para>In this example, an array of computer names is taken from the text file. A PSRemoteOperation file will be created for each computer using the same scriptblock.</maml:para>
626+
</dev:remarks>
627+
</command:example>
628+
<command:example>
629+
<maml:title>-------------------------- Example 4 --------------------------</maml:title>
630+
<dev:code>PS C:\&gt; $sb = {param([string[]]$Names,[string]$Path,[boolean]$append) restart-service $names -force -PassThru | out-file $path -append:$append -encoding ascii
631+
}
632+
PS C:\&gt; New-PSRemoteOperation -Computername SRV4 -Scriptblock $sb -ArgumentList @("spooler","bits"),"c:\work\svc.txt",$True</dev:code>
633+
<dev:remarks>
634+
<maml:para></maml:para>
635+
</dev:remarks>
636+
</command:example>
615637
</command:examples>
616638
<command:relatedLinks>
617639
<maml:navigationLink>

0 commit comments

Comments
 (0)