From 3b436bc0e39baa34a1309473c72024819f72f460 Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Tue, 19 Nov 2019 07:33:35 +0800 Subject: [PATCH 01/22] Remove helper function New-Clone and use Clone() method instead --- .../helpers/New-Clone.ps1 | 46 ------------------- .../private/Serialize-DefinitionObject.ps1 | 2 +- 2 files changed, 1 insertion(+), 47 deletions(-) delete mode 100644 src/ScheduledTaskManagement/helpers/New-Clone.ps1 diff --git a/src/ScheduledTaskManagement/helpers/New-Clone.ps1 b/src/ScheduledTaskManagement/helpers/New-Clone.ps1 deleted file mode 100644 index a0a4f98..0000000 --- a/src/ScheduledTaskManagement/helpers/New-Clone.ps1 +++ /dev/null @@ -1,46 +0,0 @@ -# Returns a deep clone of any object -function New-Clone { - param ( - # Parameter help description - [Parameter(ValueFromPipeline=$true)] - [object]$InputObject - ) - - process { - if ($null -eq $InputObject) { - return $null - } - - if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string]) { - if ($InputObject -is [System.Collections.Specialized.OrderedDictionary]) { - # It's an ordered dictionary - $orderedHash = [ordered]@{} - $InputObject.GetEnumerator() | % { - $orderedHash[$_.Name] = New-Clone -InputObject $_.Value - } - $orderedHash - }elseif ( $InputObject -is [hashtable] ) { - # It's a hashtable - $hash = [ordered]@{} - $InputObject.GetEnumerator() | % { - $hash[$_.Name] = New-Clone -InputObject $_.Value - } - $hash - }else { - # It's an array - $collection = @( - foreach ($item in $InputObject) { - New-Clone -InputObject $item - } - ) - ,$collection - } - }elseif ( $InputObject -isnot [string] -and $InputObject -isnot [int] -and $InputObject -isnot [float] -and $InputObject -isnot [double] -and $InputObject -isnot [bool] ) { - # It's a pscustomobject with properties and methods - $InputObject.Copy() - }else { - ## If the object isn't an array, collection, or dictionary, hashtable, just return it by value - $InputObject - } - } -} diff --git a/src/ScheduledTaskManagement/private/Serialize-DefinitionObject.ps1 b/src/ScheduledTaskManagement/private/Serialize-DefinitionObject.ps1 index 6c48c0e..3a2f32b 100644 --- a/src/ScheduledTaskManagement/private/Serialize-DefinitionObject.ps1 +++ b/src/ScheduledTaskManagement/private/Serialize-DefinitionObject.ps1 @@ -6,9 +6,9 @@ function Serialize-DefinitionObject { [hashtable]$DefinitionObject ) begin { - $SerializedObject = $DefinitionObject | New-Clone }process { try { + $SerializedObject = $DefinitionObject.Clone() # Serialize proerties with appropriate object values for use by scheduledtasks cmdlets if ($DefinitionObject['Trigger']) { $SerializedObject['Trigger'] = @( From f991a6395b2222c72c9ab717dc056e959a308c1b Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Tue, 19 Nov 2019 07:35:16 +0800 Subject: [PATCH 02/22] Improve returning of error object properties --- src/ScheduledTaskManagement/public/Setup-ScheduledTask.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ScheduledTaskManagement/public/Setup-ScheduledTask.ps1 b/src/ScheduledTaskManagement/public/Setup-ScheduledTask.ps1 index 64feaf3..efa601f 100644 --- a/src/ScheduledTaskManagement/public/Setup-ScheduledTask.ps1 +++ b/src/ScheduledTaskManagement/public/Setup-ScheduledTask.ps1 @@ -63,7 +63,7 @@ function Setup-ScheduledTask { try { Serialize-DefinitionObject -DefinitionObject $_ }catch { - $_ | Write-Error + Write-Error -Exception $_.Exception -Message $_.Exception.Message -Category $_.CategoryInfo.Category -TargetObject $_.TargetObject } } @@ -74,7 +74,7 @@ function Setup-ScheduledTask { try { Apply-ScheduledTask -DefinitionObject $_ }catch { - $_ | Write-Error + Write-Error -Exception $_.Exception -Message $_.Exception.Message -Category $_.CategoryInfo.Category -TargetObject $_.TargetObject } } }catch { From 9f451055a1af8edb38b5e580c5196201433278f4 Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Tue, 19 Nov 2019 07:40:11 +0800 Subject: [PATCH 03/22] Add tests --- test/scripts/dep/Install-TestDependencies.ps1 | 52 +++++ .../integration/Run-IntegrationTests.ps1 | 62 +++++ test/tasks/tasks.json | 163 +++++++++++++ test/tasks/tasks.ps1 | 219 ++++++++++++++++++ test/test.ps1 | 42 ++++ 5 files changed, 538 insertions(+) create mode 100644 test/scripts/dep/Install-TestDependencies.ps1 create mode 100644 test/scripts/integration/Run-IntegrationTests.ps1 create mode 100644 test/tasks/tasks.json create mode 100644 test/tasks/tasks.ps1 create mode 100644 test/test.ps1 diff --git a/test/scripts/dep/Install-TestDependencies.ps1 b/test/scripts/dep/Install-TestDependencies.ps1 new file mode 100644 index 0000000..37943a8 --- /dev/null +++ b/test/scripts/dep/Install-TestDependencies.ps1 @@ -0,0 +1,52 @@ +[CmdletBinding()] +param() + +$ErrorActionPreference = 'Stop' + +try { + Push-Location $PSScriptRoot + + # Install Pester if needed + "Checking Pester version" | Write-Host + $pesterMinimumVersion = [version]'4.0.0' + $pester = Get-Module 'Pester' -ListAvailable -ErrorAction SilentlyContinue + if (!$pester -or !($pester.Version -gt $pesterMinimumVersion)) { + "Installing Pester" | Write-Host + Install-Module -Name 'Pester' -Repository 'PSGallery' -MinimumVersion $pesterMinimumVersion -Scope CurrentUser -Force + } + Get-Module Pester -ListAvailable + + if ($env:OS -ne 'Windows_NT') { + if ($IsLinux) { + "Installing dependencies for linux" | Write-Host + + # Provisioning script block + $provisionScriptBlock = { + $sudo = sh -c 'command -v sudo' + $shellBin = sh -c 'command -v bash || command -v sh' + $sudo | Write-Host + $shellBin | Write-Host + "Shell command:" | Write-Verbose + $script:shellArgs | Write-Verbose + if ($sudo) { + 'Executing command with sudo' | Write-Host + & $sudo $shellBin @script:shellArgs | Write-Host + }else { + & $shellBin @script:shellArgs | Write-Host + } + if ($LASTEXITCODE) { throw "An error occurred." } + } + + # Install linux dependencies + $shellArgs = @( + 'linux/sourcepawn-dependencies.sh' + ) + & $provisionScriptBlock + } + } + +}catch { + throw +}finally{ + Pop-Location +} diff --git a/test/scripts/integration/Run-IntegrationTests.ps1 b/test/scripts/integration/Run-IntegrationTests.ps1 new file mode 100644 index 0000000..cbd4c35 --- /dev/null +++ b/test/scripts/integration/Run-IntegrationTests.ps1 @@ -0,0 +1,62 @@ +[CmdletBinding()] +param() + +$ErrorActionPreference = 'Continue' +$VerbosePreference = 'Continue' + +$failedCount = 0 + +$functionTestScriptBlock = { + try { + "Command: $script:cmd" | Write-Verbose + "Args:" | Write-Verbose + $script:cmdArgs | Out-String -Stream | % { $_.Trim() } | ? { $_ } | Write-Verbose + for ($i=0; $i -le $iterations-1; $i++) { + "Iteration: $($i+1)" | Write-Host + & $script:cmd @cmdArgs + } + }catch { + $_ | Write-Error + $script:failedCount++ + } +} + +# Function: Setup-ScheduledTask +$cmd = "Setup-ScheduledTask" +$iterations = 1 + +$cmdArgs = @{ + DefinitionFile = "$PSScriptRoot\..\..\tasks\tasks.ps1" +} +& $functionTestScriptBlock + +$cmdArgs = @{ + DefinitionFile = "$PSScriptRoot\..\..\tasks\tasks.json" + AsJson = $true +} +& $functionTestScriptBlock + +$cmdArgs = @{ + DefinitionDirectory = "$PSScriptRoot\..\..\tasks\" +} +& $functionTestScriptBlock + +$cmdArgs = @{ + DefinitionDirectory = "$PSScriptRoot\..\..\tasks\" + AsJson = $true +} +& $functionTestScriptBlock + +$cmdArgs = @{ + DefinitionObject = . "$PSScriptRoot\..\..\tasks\tasks.ps1" +} +& $functionTestScriptBlock + + +########### +# Results # +########### +if ($failedCount -gt 0) { + "$failedCount tests failed." | Write-Warning +} +$failedCount diff --git a/test/tasks/tasks.json b/test/tasks/tasks.json new file mode 100644 index 0000000..447e3bd --- /dev/null +++ b/test/tasks/tasks.json @@ -0,0 +1,163 @@ +[ + { + "Trigger": [ + { + "AtStartup": true + }, + { + "Daily": true, + "At": { + "Month": 11, + "Year": 1999, + "Hour": 17, + "Second": 0, + "Minute": 30, + "Day": 30 + }, + "DaysInterval": 1 + } + ], + "Action": [ + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item R:\\$_ }\"" + }, + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item R:\\$_ }\"" + } + ], + "Settings": { + "Disable": false, + "DontStopIfGoingOnBatteries": true, + "AllowStartIfOnBatteries": true + }, + "Principal": { + "UserId": "joe", + "LogonType": "S4U", + "RunLevel": "Highest" + }, + "TaskName": "MyTaskName1", + "TaskPath": "\\MyTaskFolder\\" + }, + { + "Trigger": [ + { + "At": { + "Month": 11, + "Year": 1999, + "Hour": 14, + "Second": 0, + "Minute": 0, + "Day": 30 + }, + "Once": true, + "RepetitionInterval": { + "Second": 0, + "Minute": 0, + "Hour": 12 + } + } + ], + "Action": [ + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item R:\\$_ }\"" + }, + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item R:\\$_ }\"" + } + ], + "Settings": { + "Disable": false, + "DontStopIfGoingOnBatteries": true, + "AllowStartIfOnBatteries": true + }, + "Principal": { + "UserId": "NT AUTHORITY\\SYSTEM", + "LogonType": "S4U", + "RunLevel": "Limited" + }, + "TaskName": "MyTaskName2", + "TaskPath": "\\MyTaskFolder\\" + }, + { + "Trigger": [ + { + "Daily": true, + "At": { + "Month": 11, + "Year": 1999, + "Hour": 10, + "Second": 0, + "Minute": 0, + "Day": 30 + }, + "DaysInterval": 1 + }, + { + "Daily": true, + "At": { + "Month": 11, + "Year": 1999, + "Hour": 14, + "Second": 0, + "Minute": 0, + "Day": 30 + }, + "DaysInterval": 1 + }, + { + "Daily": true, + "At": { + "Month": 11, + "Year": 1999, + "Hour": 18, + "Second": 0, + "Minute": 0, + "Day": 30 + }, + "DaysInterval": 1 + }, + { + "Daily": true, + "At": { + "Month": 11, + "Year": 1999, + "Hour": 22, + "Second": 0, + "Minute": 0, + "Day": 30 + }, + "DaysInterval": 1 + } + ], + "Action": [ + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item R:\\$_ }\"" + }, + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item R:\\$_ }\"" + }, + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.3 | % { New-Item R:\\$_ }\"" + } + ], + "Settings": { + "Disable": false, + "DontStopIfGoingOnBatteries": true, + "AllowStartIfOnBatteries": true + }, + "Principal": { + "UserId": "joe", + "LogonType": "S4U", + "RunLevel": "Highest" + }, + "TaskName": "MyTaskName3", + "TaskPath": "\\MyTaskFolder\\" + } +] diff --git a/test/tasks/tasks.ps1 b/test/tasks/tasks.ps1 new file mode 100644 index 0000000..3f8789c --- /dev/null +++ b/test/tasks/tasks.ps1 @@ -0,0 +1,219 @@ +@( + @{ + TaskName = 'MyTaskName1' + TaskPath = '\MyTaskFolder\' + Trigger = @( + @{ + AtStartup = $true + # At = @{ + # Year = 1999 + # Month = 11 + # Day = 30 + # Hour = 0 + # Minute = 0 + # Second = 0 + # } + # Daily = $true + # DaysInterval = 1 + # Once = $true + # RepetitionInterval = @{ + # Hour = 12 + # Minute = 0 + # Second = 0 + # } + } + @{ + # AtStartup = $true + At = @{ + Year = 1999 + Month = 11 + Day = 30 + Hour = 17 + Minute = 30 + Second = 0 + } + Daily = $true + DaysInterval = 1 + # Once = $true + # RepetitionInterval = @{ + # Hour = 12 + # Minute = 0 + # Second = 0 + # } + } + ) + Action = @( + @{ + Execute = 'powershell' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item R:\$_ }"' + } + @{ + Execute = 'powershell' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item R:\$_ }"' + } + ) + Settings = @{ + Disable = $false + AllowStartIfOnBatteries = $true + DontStopIfGoingOnBatteries = $true + } + Principal = @{ + UserId = 'joe' + LogonType = 'S4U' + RunLevel = 'Highest' + } + } + + @{ + TaskName = 'MyTaskName2' + TaskPath = '\MyTaskFolder\' + Trigger = @( + @{ + # AtStartup = $true + At = @{ + Year = 1999 + Month = 11 + Day = 30 + Hour = 14 + Minute = 0 + Second = 0 + } + # Daily = $true + # DaysInterval = 1 + Once = $true + RepetitionInterval = @{ + Hour = 12 + Minute = 0 + Second = 0 + } + } + ) + Action = @( + @{ + Execute = 'powershell' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item R:\$_ }"' + } + @{ + Execute = 'powershell' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item R:\$_ }"' + } + ) + Settings = @{ + Disable = $false + AllowStartIfOnBatteries = $true + DontStopIfGoingOnBatteries = $true + } + Principal = @{ + UserId = 'NT AUTHORITY\SYSTEM' + LogonType = 'S4U' + RunLevel = 'Limited' + } + } + + @{ + TaskName = 'MyTaskName3' + TaskPath = '\MyTaskFolder\' + Trigger = @( + @{ + # AtStartup = $true + At = @{ + Year = 1999 + Month = 11 + Day = 30 + Hour = 10 + Minute = 0 + Second = 0 + } + Daily = $true + DaysInterval = 1 + # Once = $true + # RepetitionInterval = @{ + # Hour = 12 + # Minute = 0 + # Second = 0 + # } + } + @{ + # AtStartup = $true + At = @{ + Year = 1999 + Month = 11 + Day = 30 + Hour = 14 + Minute = 0 + Second = 0 + } + Daily = $true + DaysInterval = 1 + # Once = $true + # RepetitionInterval = @{ + # Hour = 12 + # Minute = 0 + # Second = 0 + # } + } + @{ + # AtStartup = $true + At = @{ + Year = 1999 + Month = 11 + Day = 30 + Hour = 18 + Minute = 0 + Second = 0 + } + Daily = $true + DaysInterval = 1 + # Once = $true + # RepetitionInterval = @{ + # Hour = 12 + # Minute = 0 + # Second = 0 + # } + } + @{ + # AtStartup = $true + At = @{ + Year = 1999 + Month = 11 + Day = 30 + Hour = 22 + Minute = 0 + Second = 0 + } + Daily = $true + DaysInterval = 1 + # Once = $true + # RepetitionInterval = @{ + # Hour = 12 + # Minute = 0 + # Second = 0 + # } + } + ) + Action = @( + @{ + Execute = 'powershell' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item R:\$_ }"' + } + @{ + Execute = 'powershell' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item R:\$_ }"' + } + @{ + Execute = 'powershell' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.3 | % { New-Item R:\$_ }"' + } + ) + Settings = @{ + Disable = $false + AllowStartIfOnBatteries = $true + DontStopIfGoingOnBatteries = $true + } + Principal = @{ + UserId = 'joe' + LogonType = 'S4U' + RunLevel = 'Highest' + } + } +) diff --git a/test/test.ps1 b/test/test.ps1 new file mode 100644 index 0000000..98fc0fb --- /dev/null +++ b/test/test.ps1 @@ -0,0 +1,42 @@ +[CmdletBinding()] +param() + +Set-StrictMode -Version Latest +$VerbosePreference = 'Continue' +$global:PesterDebugPreference_ShowFullErrors = $true + +try { + Push-Location $PSScriptRoot + + # Install test dependencies + "Installing test dependencies" | Write-Host + & "$PSScriptRoot\scripts\dep\Install-TestDependencies.ps1" > $null + + # Run unit tests + "Running unit tests" | Write-Host + $testFailed = $false + $unitResult = Invoke-Pester -Script "$PSScriptRoot\..\src\Compile-SourceScript" -PassThru + if ($unitResult.FailedCount -gt 0) { + "$($unitResult.FailedCount) tests failed." | Write-Warning + $testFailed = $true + } + + # Run integration tests + "Running integration tests" | Write-Host + $integratedFailedCount = & "$PSScriptRoot\scripts\integration\Run-IntegrationTests.ps1" + if ($integratedFailedCount -gt 0) { + $testFailed = $true + } + + "Listing test artifacts" | Write-Host + git ls-files --others --exclude-standard + + "End of tests" | Write-Host + if ($testFailed) { + throw "One or more tests failed." + } +}catch { + throw +}finally { + Pop-Location +} From 07ce5b9b8221faafb1b9db1ed9d767030a5a3e63 Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Tue, 19 Nov 2019 08:16:58 +0800 Subject: [PATCH 04/22] Rrename Public and Private directories --- .../{private => Private}/Apply-ScheduledTask.ps1 | 0 .../{private => Private}/Serialize-DefinitionObject.ps1 | 0 .../{private => Private}/Validate-DefinitionObject.ps1 | 0 .../{public => Public}/Setup-ScheduledTask.ps1 | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename src/ScheduledTaskManagement/{private => Private}/Apply-ScheduledTask.ps1 (100%) rename src/ScheduledTaskManagement/{private => Private}/Serialize-DefinitionObject.ps1 (100%) rename src/ScheduledTaskManagement/{private => Private}/Validate-DefinitionObject.ps1 (100%) rename src/ScheduledTaskManagement/{public => Public}/Setup-ScheduledTask.ps1 (100%) diff --git a/src/ScheduledTaskManagement/private/Apply-ScheduledTask.ps1 b/src/ScheduledTaskManagement/Private/Apply-ScheduledTask.ps1 similarity index 100% rename from src/ScheduledTaskManagement/private/Apply-ScheduledTask.ps1 rename to src/ScheduledTaskManagement/Private/Apply-ScheduledTask.ps1 diff --git a/src/ScheduledTaskManagement/private/Serialize-DefinitionObject.ps1 b/src/ScheduledTaskManagement/Private/Serialize-DefinitionObject.ps1 similarity index 100% rename from src/ScheduledTaskManagement/private/Serialize-DefinitionObject.ps1 rename to src/ScheduledTaskManagement/Private/Serialize-DefinitionObject.ps1 diff --git a/src/ScheduledTaskManagement/private/Validate-DefinitionObject.ps1 b/src/ScheduledTaskManagement/Private/Validate-DefinitionObject.ps1 similarity index 100% rename from src/ScheduledTaskManagement/private/Validate-DefinitionObject.ps1 rename to src/ScheduledTaskManagement/Private/Validate-DefinitionObject.ps1 diff --git a/src/ScheduledTaskManagement/public/Setup-ScheduledTask.ps1 b/src/ScheduledTaskManagement/Public/Setup-ScheduledTask.ps1 similarity index 100% rename from src/ScheduledTaskManagement/public/Setup-ScheduledTask.ps1 rename to src/ScheduledTaskManagement/Public/Setup-ScheduledTask.ps1 From 0fac147e324464a8dc4ce41c8b90e5cf68c59deb Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 15:01:40 +0800 Subject: [PATCH 05/22] Remove ParameterSetName 'AsJson' --- src/ScheduledTaskManagement/Public/Setup-ScheduledTask.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScheduledTaskManagement/Public/Setup-ScheduledTask.ps1 b/src/ScheduledTaskManagement/Public/Setup-ScheduledTask.ps1 index efa601f..387b6f0 100644 --- a/src/ScheduledTaskManagement/Public/Setup-ScheduledTask.ps1 +++ b/src/ScheduledTaskManagement/Public/Setup-ScheduledTask.ps1 @@ -15,7 +15,7 @@ function Setup-ScheduledTask { [ValidateNotNullOrEmpty()] [object[]]$DefinitionObject , - [Parameter(ParameterSetName='AsJson', Mandatory=$false)] + [Parameter(Mandatory=$false)] [Parameter(ParameterSetName='DefinitionFile')] [Parameter(ParameterSetName='DefinitionDirectory')] [switch]$AsJson From 8588e148f3f6795e1504e9b220db647e5dfe535c Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 15:07:12 +0800 Subject: [PATCH 06/22] Update readme --- README.md | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 151 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3ced666..e206895 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,166 @@ # ScheduledTaskManagement +[![badge-build-azuredevops-build-img][]][badge-build-azuredevops-build-src] [![badge-version-github-release-img][]][badge-version-github-release-src] [![badge-version-powershellgallery-releases-img][]][badge-version-powershellgallery-releases-src] + +[badge-build-azuredevops-build-img]: https://img.shields.io/azure-devops/build/joeltimothyoh/ScheduledTaskManagement/19/master.svg?label=build&logo=azure-pipelines&style=flat-square +[badge-build-azuredevops-build-src]: https://dev.azure.com/joeltimothyoh/ScheduledTaskManagement/_build?definitionId=19 +[badge-version-github-release-img]: https://img.shields.io/github/v/release/joeltimothyoh/ScheduledTaskManagement?style=flat-square +[badge-version-github-release-src]: https://github.com/joeltimothyoh/ScheduledTaskManagement/releases +[badge-version-powershellgallery-releases-img]: https://img.shields.io/powershellgallery/v/ScheduledTaskManagement?logo=powershell&logoColor=white&label=PSGallery&labelColor=&style=flat-square +[badge-version-powershellgallery-releases-src]: https://www.powershellgallery.com/packages/ScheduledTaskManagement/ + +## Introduction + +A PowerShell module for non-interactive management of Scheduled Tasks. + +## Requirements + +* **Windows** with [PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-6). + +## Installation + +First, ensure [`PSGallery`](https://www.powershellgallery.com/) is registered as a PowerShell repository: + ```powershell -Import-Module .\src\ScheduledTaskManagement\ScheduledTaskManagement.psm1 -Force -Verbose +Register-PSRepository -Default -Verbose +``` + +To install the module: + +```powershell +# Latest, for the current user +Install-Module -Name ScheduledTaskManagement -Repository PSGallery -Scope CurrentUser -Verbose + +# Specific version, for the current user +Install-Module -Name ScheduledTaskManagement -Repository PSGallery -RequiredVersion x.x.x -Scope CurrentUser -Verbose + +# Latest, for all users +Install-Module -Name ScheduledTaskManagement -Repository PSGallery -Scope AllUsers -Verbose +``` + +## Usage + +### Functions + +#### Parameters -# .ps1 definition file +```powershell +Setup-ScheduledTask -DefinitionFile [-AsJson] [] + +Setup-ScheduledTask -DefinitionDirectory [-AsJson] [] + +Setup-ScheduledTask -DefinitionObject [] +``` + +#### Examples + +```powershell +# Via .ps1 definition file Setup-ScheduledTask -DefinitionFile "C:\path\to\definition.ps1" -# .json definition file +# Via .json definition file Setup-ScheduledTask -DefinitionFile "C:\path\to\definition.json" -AsJson -# Directory containing .ps1 definition files +# Via directory containing .ps1 definition files Setup-ScheduledTask -DefinitionDirectory "C:\path\to\definition\directory\" -# Directory containing .json definition files +# Via directory containing .json definition files Setup-ScheduledTask -DefinitionDirectory "C:\path\to\definition\directory\" -AsJson -# Definition objects -Setup-ScheduledTask -DefinitionObject $objects +# Via definition objects +$tasks = . "C:\path\to\definition.ps1" +Setup-ScheduledTask -DefinitionObject $tasks +``` + +To list all available functions of the module: + +```powershell +Get-Command -Module ScheduledTaskManagement +``` + +## Administration + +### Versions + +To list versions of the module on `PSGallery`: + +```powershell +# Latest +Find-Module -Name ScheduledTaskManagement -Repository PSGallery -Verbose + +# All versions +Find-Module -Name ScheduledTaskManagement -Repository PSGallery -AllVersions -Verbose +``` + +To update the module (**Existing versions are left intact**): + +```powershell +# Latest +Update-Module -Name ScheduledTaskManagement -Verbose + +# Specific version +Update-Module -Name ScheduledTaskManagement -RequiredVersion x.x.x -Verbose +``` + +To uninstall the module: + +```powershell +# Latest +Uninstall-Module -Name ScheduledTaskManagement -Verbose + +# All versions +Uninstall-Module -Name ScheduledTaskManagement -AllVersions -Verbose + +# To uninstall all other versions other than x.x.x +Get-Module -Name ScheduledTaskManagement -ListAvailable | ? { $_.Version -ne 'x.x.x' } | % { Uninstall-Module -Name $_.Name -RequiredVersion $_.Version -Verbose } + +# Tip: Simulate uninstalls with -WhatIf +``` + +### Repositories + +To get all registered PowerShell repositories: + +```powershell +Get-PSRepository -Verbose +``` + +To set the installation policy for the `PSGallery` repository: + +```powershell +# PSGallery (trusted) +Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -Verbose + +# PSGallery (untrusted) +Set-PSRepository -Name PSGallery -InstallationPolicy Untrusted -Verbose +``` + +### Development + +To import / re-import the module: + +```powershell +# Installed version +Import-Module -Name ScheduledTaskManagement -Force -Verbose + +# Project version +Import-Module .\src\ScheduledTaskManagement\ScheduledTaskManagement.psm1 -Force -Verbose ``` -## Tips +To remove imported functions of the module: -- `-DefinitionFile`, `-DefinitionDirectory`, and `-DefinitionObject` accept an array of objects. -- You can use the `-Verbose` for verbose output. +```powershell +Remove-Module -Name ScheduledTaskManagement -Verbose +``` + +To list imported versions of the module: + +```powershell +Get-Module -Name ScheduledTaskManagement +``` + +To list all installed versions of the module available for import: + +```powershell +Get-Module -Name ScheduledTaskManagement -ListAvailable -Verbose +``` From 8ab4c1c5c8782abc6a4093a3f765b07914cffe6e Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Tue, 19 Nov 2019 06:37:46 +0800 Subject: [PATCH 07/22] Add submodule PSModulePublisher v0.3.2 --- .gitmodules | 3 +++ build/PSModulePublisher | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 build/PSModulePublisher diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..8e5a555 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "build/PSModulePublisher"] + path = build/PSModulePublisher + url = https://github.com/theohbrothers/PSModulePublisher.git diff --git a/build/PSModulePublisher b/build/PSModulePublisher new file mode 160000 index 0000000..c91b4e7 --- /dev/null +++ b/build/PSModulePublisher @@ -0,0 +1 @@ +Subproject commit c91b4e794f81da08a1f6fca86dcc10891021430e From 8df06c64286648a39bada6877b7845bed06f69eb Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 15:11:47 +0800 Subject: [PATCH 08/22] Add module manifest definition --- .../definitions/modulemanifest/definition.ps1 | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 build/definitions/modulemanifest/definition.ps1 diff --git a/build/definitions/modulemanifest/definition.ps1 b/build/definitions/modulemanifest/definition.ps1 new file mode 100644 index 0000000..f35dcfe --- /dev/null +++ b/build/definitions/modulemanifest/definition.ps1 @@ -0,0 +1,53 @@ +# - Initial setup: Fill in the GUID value. Generate one by running the command 'New-GUID'. Then fill in all relevant details. +# - Ensure all relevant details are updated prior to publishing each version of the module. +# - To simulate generation of the manifest based on this definition, run the included development entrypoint script Invoke-PSModulePublisher.ps1. +# - To publish the module, tag the associated commit and push the tag. + +@{ + RootModule = 'ScheduledTaskManagement.psm1' + # ModuleVersion = '' # Value will be set for each publication based on the tag ref. Defaults to '0.0.0' in development environments and regular CI builds + GUID = 'df816621-ce49-41d2-8523-19122d51c3a4' + Author = 'The Oh Brothers' + CompanyName = 'The Oh Brothers' + Copyright = '(c) 2019 The Oh Brothers' + Description = 'A PowerShell module for non-interactive management of Scheduled Tasks.' + PowerShellVersion = '3.0' + # PowerShellHostName = '' + # PowerShellHostVersion = '' + # DotNetFrameworkVersion = '' + # CLRVersion = '' + # ProcessorArchitecture = '' + # RequiredModules = @() + # RequiredAssemblies = @() + # ScriptsToProcess = @() + # TypesToProcess = @() + # FormatsToProcess = @() + # NestedModules = @() + FunctionsToExport = @( + 'Setup-ScheduledTask' + ) + CmdletsToExport = @() + VariablesToExport = @() + AliasesToExport = @() + # DscResourcesToExport = @() + # ModuleList = @() + # FileList = @() + PrivateData = @{ + # PSData = @{ # Properties within PSData will be correctly added to the manifest via Update-ModuleManifest without the PSData key. Leave the key commented out. + Tags = @( + 'taskscheduler' + 'scheduledtasks' + 'tasks' + ) + LicenseUri = 'https://raw.githubusercontent.com/theohbrothers/ScheduledTaskManagement/master/LICENSE' + ProjectUri = 'https://github.com/theohbrothers/ScheduledTaskManagement' + # IconUri = '' + # ReleaseNotes = '' + # Prerelease = '' + # RequireLicenseAcceptance = $false + # ExternalModuleDependencies = @() + # } + # HelpInfoURI = '' + # DefaultCommandPrefix = '' + } +} From 7586af8d0978093ae787e08710dcd2a5e2303d60 Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 15:18:22 +0800 Subject: [PATCH 09/22] Add capturing of stdout in integrated tests which is then output in verbose stream --- test/scripts/integration/Run-IntegrationTests.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/scripts/integration/Run-IntegrationTests.ps1 b/test/scripts/integration/Run-IntegrationTests.ps1 index cbd4c35..6a55e6c 100644 --- a/test/scripts/integration/Run-IntegrationTests.ps1 +++ b/test/scripts/integration/Run-IntegrationTests.ps1 @@ -13,7 +13,8 @@ $functionTestScriptBlock = { $script:cmdArgs | Out-String -Stream | % { $_.Trim() } | ? { $_ } | Write-Verbose for ($i=0; $i -le $iterations-1; $i++) { "Iteration: $($i+1)" | Write-Host - & $script:cmd @cmdArgs + $stdout = & $script:cmd @cmdArgs + $stdout | Out-String -Stream | % { $_.Trim() } | ? { $_ } | Write-Verbose } }catch { $_ | Write-Error From 0b8725a156d158d41629b02772567c6ba06cc03c Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 15:24:24 +0800 Subject: [PATCH 10/22] Relocate test scheduled task definitions directory --- test/{tasks => definitions/scheduledtasks}/tasks.json | 0 test/{tasks => definitions/scheduledtasks}/tasks.ps1 | 0 test/scripts/integration/Run-IntegrationTests.ps1 | 10 +++++----- 3 files changed, 5 insertions(+), 5 deletions(-) rename test/{tasks => definitions/scheduledtasks}/tasks.json (100%) rename test/{tasks => definitions/scheduledtasks}/tasks.ps1 (100%) diff --git a/test/tasks/tasks.json b/test/definitions/scheduledtasks/tasks.json similarity index 100% rename from test/tasks/tasks.json rename to test/definitions/scheduledtasks/tasks.json diff --git a/test/tasks/tasks.ps1 b/test/definitions/scheduledtasks/tasks.ps1 similarity index 100% rename from test/tasks/tasks.ps1 rename to test/definitions/scheduledtasks/tasks.ps1 diff --git a/test/scripts/integration/Run-IntegrationTests.ps1 b/test/scripts/integration/Run-IntegrationTests.ps1 index 6a55e6c..0d0b724 100644 --- a/test/scripts/integration/Run-IntegrationTests.ps1 +++ b/test/scripts/integration/Run-IntegrationTests.ps1 @@ -27,29 +27,29 @@ $cmd = "Setup-ScheduledTask" $iterations = 1 $cmdArgs = @{ - DefinitionFile = "$PSScriptRoot\..\..\tasks\tasks.ps1" + DefinitionFile = "$PSScriptRoot\..\..\definitions\scheduledtasks\tasks.ps1" } & $functionTestScriptBlock $cmdArgs = @{ - DefinitionFile = "$PSScriptRoot\..\..\tasks\tasks.json" + DefinitionFile = "$PSScriptRoot\..\..\definitions\scheduledtasks\tasks.json" AsJson = $true } & $functionTestScriptBlock $cmdArgs = @{ - DefinitionDirectory = "$PSScriptRoot\..\..\tasks\" + DefinitionDirectory = "$PSScriptRoot\..\..\definitions\scheduledtasks\" } & $functionTestScriptBlock $cmdArgs = @{ - DefinitionDirectory = "$PSScriptRoot\..\..\tasks\" + DefinitionDirectory = "$PSScriptRoot\..\..\definitions\scheduledtasks\" AsJson = $true } & $functionTestScriptBlock $cmdArgs = @{ - DefinitionObject = . "$PSScriptRoot\..\..\tasks\tasks.ps1" + DefinitionObject = . "$PSScriptRoot\..\..\definitions\scheduledtasks\tasks.ps1" } & $functionTestScriptBlock From a03a8ca0c3f8334a8d5d2c038d24389fa4fe7c53 Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 15:36:05 +0800 Subject: [PATCH 11/22] Update principal in test schedule task definitions --- test/definitions/scheduledtasks/tasks.json | 4 ++-- test/definitions/scheduledtasks/tasks.ps1 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/definitions/scheduledtasks/tasks.json b/test/definitions/scheduledtasks/tasks.json index 447e3bd..22e3eac 100644 --- a/test/definitions/scheduledtasks/tasks.json +++ b/test/definitions/scheduledtasks/tasks.json @@ -33,7 +33,7 @@ "AllowStartIfOnBatteries": true }, "Principal": { - "UserId": "joe", + "UserId": "VssAdministrator", "LogonType": "S4U", "RunLevel": "Highest" }, @@ -153,7 +153,7 @@ "AllowStartIfOnBatteries": true }, "Principal": { - "UserId": "joe", + "UserId": "VssAdministrator", "LogonType": "S4U", "RunLevel": "Highest" }, diff --git a/test/definitions/scheduledtasks/tasks.ps1 b/test/definitions/scheduledtasks/tasks.ps1 index 3f8789c..a3802d8 100644 --- a/test/definitions/scheduledtasks/tasks.ps1 +++ b/test/definitions/scheduledtasks/tasks.ps1 @@ -58,7 +58,7 @@ DontStopIfGoingOnBatteries = $true } Principal = @{ - UserId = 'joe' + UserId = 'VssAdministrator' LogonType = 'S4U' RunLevel = 'Highest' } @@ -211,7 +211,7 @@ DontStopIfGoingOnBatteries = $true } Principal = @{ - UserId = 'joe' + UserId = 'VssAdministrator' LogonType = 'S4U' RunLevel = 'Highest' } From 3876f21123079a56068eb85f700c6836780be7ce Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 15:38:04 +0800 Subject: [PATCH 12/22] Add scheduled task json definition sample --- .../scheduledtasks/tasks.json.sample | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 docs/samples/definitions/scheduledtasks/tasks.json.sample diff --git a/docs/samples/definitions/scheduledtasks/tasks.json.sample b/docs/samples/definitions/scheduledtasks/tasks.json.sample new file mode 100644 index 0000000..c38cfc0 --- /dev/null +++ b/docs/samples/definitions/scheduledtasks/tasks.json.sample @@ -0,0 +1,163 @@ +[ + { + "Trigger": [ + { + "AtStartup": true + }, + { + "Daily": true, + "At": { + "Month": 11, + "Year": 1999, + "Hour": 17, + "Second": 0, + "Minute": 30, + "Day": 30 + }, + "DaysInterval": 1 + } + ], + "Action": [ + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item R:\\$_ }\"" + }, + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item R:\\$_ }\"" + } + ], + "Settings": { + "Disable": false, + "DontStopIfGoingOnBatteries": true, + "AllowStartIfOnBatteries": true + }, + "Principal": { + "UserId": "myusername", + "LogonType": "S4U", + "RunLevel": "Highest" + }, + "TaskName": "MyTaskName1", + "TaskPath": "\\MyTaskFolder\\" + }, + { + "Trigger": [ + { + "At": { + "Month": 11, + "Year": 1999, + "Hour": 14, + "Second": 0, + "Minute": 0, + "Day": 30 + }, + "Once": true, + "RepetitionInterval": { + "Second": 0, + "Minute": 0, + "Hour": 12 + } + } + ], + "Action": [ + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item R:\\$_ }\"" + }, + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item R:\\$_ }\"" + } + ], + "Settings": { + "Disable": false, + "DontStopIfGoingOnBatteries": true, + "AllowStartIfOnBatteries": true + }, + "Principal": { + "UserId": "NT AUTHORITY\\SYSTEM", + "LogonType": "S4U", + "RunLevel": "Limited" + }, + "TaskName": "MyTaskName2", + "TaskPath": "\\MyTaskFolder\\" + }, + { + "Trigger": [ + { + "Daily": true, + "At": { + "Month": 11, + "Year": 1999, + "Hour": 10, + "Second": 0, + "Minute": 0, + "Day": 30 + }, + "DaysInterval": 1 + }, + { + "Daily": true, + "At": { + "Month": 11, + "Year": 1999, + "Hour": 14, + "Second": 0, + "Minute": 0, + "Day": 30 + }, + "DaysInterval": 1 + }, + { + "Daily": true, + "At": { + "Month": 11, + "Year": 1999, + "Hour": 18, + "Second": 0, + "Minute": 0, + "Day": 30 + }, + "DaysInterval": 1 + }, + { + "Daily": true, + "At": { + "Month": 11, + "Year": 1999, + "Hour": 22, + "Second": 0, + "Minute": 0, + "Day": 30 + }, + "DaysInterval": 1 + } + ], + "Action": [ + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item R:\\$_ }\"" + }, + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item R:\\$_ }\"" + }, + { + "Execute": "powershell", + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.3 | % { New-Item R:\\$_ }\"" + } + ], + "Settings": { + "Disable": false, + "DontStopIfGoingOnBatteries": true, + "AllowStartIfOnBatteries": true + }, + "Principal": { + "UserId": "myusername", + "LogonType": "S4U", + "RunLevel": "Highest" + }, + "TaskName": "MyTaskName3", + "TaskPath": "\\MyTaskFolder\\" + } +] From 0c0e6773074fedeec2a4f1e0f951166a2544b48d Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 15:25:45 +0800 Subject: [PATCH 13/22] Add azure-pipelines.yml --- azure-pipelines.yml | 77 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 azure-pipelines.yml diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..b9be8de --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,77 @@ +trigger: + branches: + include: + - '*' + tags: + include: + - '*' +pr: + autoCancel: false + branches: + include: + - '*' + +resources: + repositories: + - repository: PSModulePublisher + type: github + name: theohbrothers/PSModulePublisher + endpoint: theohbrothers # Check for your 'Type: Github' connection under 'Project Settings' > 'Service connections' + ref: refs/tags/v0.3.2 + +stages: +- stage: build_test + displayName: Build, Test + jobs: + - job: windows_pwsh + displayName: '[Windows] PowerShell Core' + pool: + vmImage: windows-2019 + steps: + - checkout: self + submodules: recursive + - template: templates/azure-pipelines/entrypoint/windows/continuous-build.yml@PSModulePublisher + - job: windows_powershell_5_1 + displayName: '[Windows] PowerShell 5.1' + pool: + vmImage: windows-2019 + steps: + - checkout: self + submodules: recursive + - template: templates/azure-pipelines/entrypoint/windows/powershell/continuous-build.yml@PSModulePublisher + - job: windows_powershell_5_0 + displayName: '[Windows] PowerShell 5.0' + pool: + vmImage: vs2015-win2012r2 + steps: + - checkout: self + submodules: recursive + - template: templates/azure-pipelines/entrypoint/windows/powershell/continuous-build.yml@PSModulePublisher + - job: windows_1803 + displayName: '[Windows Server Core 1803] Windows PowerShell' + pool: + vmImage: win1803 + steps: + - checkout: self + submodules: recursive + - template: templates/azure-pipelines/entrypoint/windows/powershell/continuous-build.yml@PSModulePublisher + - job: windows_2016 + displayName: '[Windows Server 2016] Windows PowerShell' + pool: + vmImage: vs2017-win2016 + steps: + - checkout: self + submodules: recursive + - template: templates/azure-pipelines/entrypoint/windows/powershell/continuous-build.yml@PSModulePublisher +- stage: publish + displayName: Publish + dependsOn: build_test + jobs: + - job: windows_powershell_5_1 + displayName: '[Windows] PowerShell 5.1' + pool: + vmImage: windows-2019 + steps: + - checkout: self + submodules: recursive + - template: templates/azure-pipelines/entrypoint/windows/powershell/continuous-build.yml@PSModulePublisher From c44d8bcdc8d74261d11c68a91b4231ff10764232 Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 16:22:05 +0800 Subject: [PATCH 14/22] Update readme --- README.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e206895..2c11ff9 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ A PowerShell module for non-interactive management of Scheduled Tasks. ## Requirements -* **Windows** with [PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-6). +* **Windows** with [PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell). ## Installation @@ -40,15 +40,28 @@ Install-Module -Name ScheduledTaskManagement -Repository PSGallery -Scope AllUse ## Usage +### Scheduled tasks + +To create scheduled tasks, first define the properties of each task in `.ps1` or `.json` definition file(s). Then feed each definition file path, directory path, or definition array objects to `Setup-ScheduledTask` to create them non-interactively. + +The properties of each task definition object are based off the following cmdlets from the [`ScheduledTasks`](https://docs.microsoft.com/en-us/powershell/module/scheduledtasks) module, making them customizable and extensible: + +```powershell +New-ScheduledTaskTrigger +New-ScheduledTaskAction +New-ScheduledTaskSettingsSet +New-ScheduledTaskPrincipal +``` + +Sample defintion files can be found [here](docs/samples/definitions/scheduledtasks). + ### Functions #### Parameters ```powershell Setup-ScheduledTask -DefinitionFile [-AsJson] [] - Setup-ScheduledTask -DefinitionDirectory [-AsJson] [] - Setup-ScheduledTask -DefinitionObject [] ``` From f2010745c19e7d1e0fdebb054edc716e1254e401 Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 16:30:19 +0800 Subject: [PATCH 15/22] Fix module directory in test entrypoint script --- test/test.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.ps1 b/test/test.ps1 index 98fc0fb..bc040a9 100644 --- a/test/test.ps1 +++ b/test/test.ps1 @@ -15,7 +15,7 @@ try { # Run unit tests "Running unit tests" | Write-Host $testFailed = $false - $unitResult = Invoke-Pester -Script "$PSScriptRoot\..\src\Compile-SourceScript" -PassThru + $unitResult = Invoke-Pester -Script "$PSScriptRoot\..\src\ScheduledTaskManagement" -PassThru if ($unitResult.FailedCount -gt 0) { "$($unitResult.FailedCount) tests failed." | Write-Warning $testFailed = $true From 8849047c4c4e794ef274260c5208c2e6292cf001 Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 18:28:26 +0800 Subject: [PATCH 16/22] Add New-ScheduledTaskTrigger -RepetitionDuration property support --- .../scheduledtasks/definition.ps1.sample | 21 +++++++++++++++++ .../scheduledtasks/tasks.json.sample | 3 +++ .../Private/Serialize-DefinitionObject.ps1 | 3 +++ test/definitions/scheduledtasks/tasks.json | 3 +++ test/definitions/scheduledtasks/tasks.ps1 | 23 ++++++++++++++++++- 5 files changed, 52 insertions(+), 1 deletion(-) diff --git a/docs/samples/definitions/scheduledtasks/definition.ps1.sample b/docs/samples/definitions/scheduledtasks/definition.ps1.sample index 112be71..0a41d20 100644 --- a/docs/samples/definitions/scheduledtasks/definition.ps1.sample +++ b/docs/samples/definitions/scheduledtasks/definition.ps1.sample @@ -21,6 +21,9 @@ # Minute = 0 # Second = 0 # } + # RepetitionDuration = @{ + # Days = 9999 + # } } @{ # AtStartup = $true @@ -35,6 +38,9 @@ Daily = $true DaysInterval = 1 # Once = $true + # RepetitionDuration = @{ + # Days = 9999 + # } # RepetitionInterval = @{ # Hour = 12 # Minute = 0 @@ -81,6 +87,9 @@ # Daily = $true # DaysInterval = 1 Once = $true + # RepetitionDuration = @{ + # Days = 9999 + # } RepetitionInterval = @{ Hour = 12 Minute = 0 @@ -127,6 +136,9 @@ Daily = $true DaysInterval = 1 # Once = $true + # RepetitionDuration = @{ + # Days = 9999 + # } # RepetitionInterval = @{ # Hour = 12 # Minute = 0 @@ -146,6 +158,9 @@ Daily = $true DaysInterval = 1 # Once = $true + # RepetitionDuration = @{ + # Days = 9999 + # } # RepetitionInterval = @{ # Hour = 12 # Minute = 0 @@ -165,6 +180,9 @@ Daily = $true DaysInterval = 1 # Once = $true + # RepetitionDuration = @{ + # Days = 9999 + # } # RepetitionInterval = @{ # Hour = 12 # Minute = 0 @@ -184,6 +202,9 @@ Daily = $true DaysInterval = 1 # Once = $true + # RepetitionDuration = @{ + # Days = 9999 + # } # RepetitionInterval = @{ # Hour = 12 # Minute = 0 diff --git a/docs/samples/definitions/scheduledtasks/tasks.json.sample b/docs/samples/definitions/scheduledtasks/tasks.json.sample index c38cfc0..6eece9c 100644 --- a/docs/samples/definitions/scheduledtasks/tasks.json.sample +++ b/docs/samples/definitions/scheduledtasks/tasks.json.sample @@ -56,6 +56,9 @@ "Second": 0, "Minute": 0, "Hour": 12 + }, + "RepetitionDuration": { + "Days": 9999 } } ], diff --git a/src/ScheduledTaskManagement/Private/Serialize-DefinitionObject.ps1 b/src/ScheduledTaskManagement/Private/Serialize-DefinitionObject.ps1 index 3a2f32b..844f6d3 100644 --- a/src/ScheduledTaskManagement/Private/Serialize-DefinitionObject.ps1 +++ b/src/ScheduledTaskManagement/Private/Serialize-DefinitionObject.ps1 @@ -19,6 +19,9 @@ function Serialize-DefinitionObject { if ($_.Key -eq 'At') { $d = $_.Value $triggerTemp[$_.Key] = Get-Date @d + }elseif ($_.Key -eq 'RepetitionDuration') { + $t = $_.Value + $triggerTemp[$_.Key] = New-Timespan @t }elseif ($_.Key -eq 'RepetitionInterval') { $t = $_.Value $triggerTemp[$_.Key] = New-Timespan @t diff --git a/test/definitions/scheduledtasks/tasks.json b/test/definitions/scheduledtasks/tasks.json index 22e3eac..517b3a4 100644 --- a/test/definitions/scheduledtasks/tasks.json +++ b/test/definitions/scheduledtasks/tasks.json @@ -56,6 +56,9 @@ "Second": 0, "Minute": 0, "Hour": 12 + }, + "RepetitionDuration": { + "Days": 9999 } } ], diff --git a/test/definitions/scheduledtasks/tasks.ps1 b/test/definitions/scheduledtasks/tasks.ps1 index a3802d8..6b84555 100644 --- a/test/definitions/scheduledtasks/tasks.ps1 +++ b/test/definitions/scheduledtasks/tasks.ps1 @@ -21,6 +21,9 @@ # Minute = 0 # Second = 0 # } + # RepetitionDuration = @{ + # Days = 9999 + # } } @{ # AtStartup = $true @@ -35,6 +38,9 @@ Daily = $true DaysInterval = 1 # Once = $true + # RepetitionDuration = @{ + # Days = 9999 + # } # RepetitionInterval = @{ # Hour = 12 # Minute = 0 @@ -81,6 +87,9 @@ # Daily = $true # DaysInterval = 1 Once = $true + RepetitionDuration = @{ + Days = 9999 + } RepetitionInterval = @{ Hour = 12 Minute = 0 @@ -111,7 +120,7 @@ } @{ - TaskName = 'MyTaskName3' + TaskName = 'MyTaskName4' TaskPath = '\MyTaskFolder\' Trigger = @( @{ @@ -127,6 +136,9 @@ Daily = $true DaysInterval = 1 # Once = $true + # RepetitionDuration = @{ + # Days = 9999 + # } # RepetitionInterval = @{ # Hour = 12 # Minute = 0 @@ -146,6 +158,9 @@ Daily = $true DaysInterval = 1 # Once = $true + # RepetitionDuration = @{ + # Days = 9999 + # } # RepetitionInterval = @{ # Hour = 12 # Minute = 0 @@ -165,6 +180,9 @@ Daily = $true DaysInterval = 1 # Once = $true + # RepetitionDuration = @{ + # Days = 9999 + # } # RepetitionInterval = @{ # Hour = 12 # Minute = 0 @@ -184,6 +202,9 @@ Daily = $true DaysInterval = 1 # Once = $true + # RepetitionDuration = @{ + # Days = 9999 + # } # RepetitionInterval = @{ # Hour = 12 # Minute = 0 From 4bc3033c73aae4f12a1fce8c739a5041be041822 Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 18:30:25 +0800 Subject: [PATCH 17/22] Remove RepetitionDuration property from definition in tasks json sample --- docs/samples/definitions/scheduledtasks/tasks.json.sample | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/samples/definitions/scheduledtasks/tasks.json.sample b/docs/samples/definitions/scheduledtasks/tasks.json.sample index 6eece9c..c38cfc0 100644 --- a/docs/samples/definitions/scheduledtasks/tasks.json.sample +++ b/docs/samples/definitions/scheduledtasks/tasks.json.sample @@ -56,9 +56,6 @@ "Second": 0, "Minute": 0, "Hour": 12 - }, - "RepetitionDuration": { - "Days": 9999 } } ], From 7808f5205f7c2d497a632448db37c66be7b58388 Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 18:32:13 +0800 Subject: [PATCH 18/22] Fix regression in test task name --- test/definitions/scheduledtasks/tasks.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/definitions/scheduledtasks/tasks.ps1 b/test/definitions/scheduledtasks/tasks.ps1 index 6b84555..2218fd9 100644 --- a/test/definitions/scheduledtasks/tasks.ps1 +++ b/test/definitions/scheduledtasks/tasks.ps1 @@ -120,7 +120,7 @@ } @{ - TaskName = 'MyTaskName4' + TaskName = 'MyTaskName3' TaskPath = '\MyTaskFolder\' Trigger = @( @{ From 1ada8c96782e8957ff596c01a7703fb548e8f3b0 Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 18:03:22 +0800 Subject: [PATCH 19/22] Update readme badges --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2c11ff9..fa2c2d8 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ [![badge-build-azuredevops-build-img][]][badge-build-azuredevops-build-src] [![badge-version-github-release-img][]][badge-version-github-release-src] [![badge-version-powershellgallery-releases-img][]][badge-version-powershellgallery-releases-src] -[badge-build-azuredevops-build-img]: https://img.shields.io/azure-devops/build/joeltimothyoh/ScheduledTaskManagement/19/master.svg?label=build&logo=azure-pipelines&style=flat-square -[badge-build-azuredevops-build-src]: https://dev.azure.com/joeltimothyoh/ScheduledTaskManagement/_build?definitionId=19 -[badge-version-github-release-img]: https://img.shields.io/github/v/release/joeltimothyoh/ScheduledTaskManagement?style=flat-square -[badge-version-github-release-src]: https://github.com/joeltimothyoh/ScheduledTaskManagement/releases +[badge-build-azuredevops-build-img]: https://img.shields.io/azure-devops/build/theohbrothers/ScheduledTaskManagement/8/master.svg?label=build&logo=azure-pipelines&style=flat-square +[badge-build-azuredevops-build-src]: https://dev.azure.com/theohbrothers/ScheduledTaskManagement/_build?definitionId=8 +[badge-version-github-release-img]: https://img.shields.io/github/v/release/theohbrothers/ScheduledTaskManagement?style=flat-square +[badge-version-github-release-src]: https://github.com/theohbrothers/ScheduledTaskManagement/releases [badge-version-powershellgallery-releases-img]: https://img.shields.io/powershellgallery/v/ScheduledTaskManagement?logo=powershell&logoColor=white&label=PSGallery&labelColor=&style=flat-square [badge-version-powershellgallery-releases-src]: https://www.powershellgallery.com/packages/ScheduledTaskManagement/ From e46f6e0855c1ba6141dbf5c5ef731f180a0df96e Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 18:39:59 +0800 Subject: [PATCH 20/22] Add submodule PSRepositoryReleaseManager v0.5.2 --- .gitmodules | 3 +++ azure-pipelines.yml | 20 ++++++++++++++++++++ build/PSRepositoryReleaseManager | 1 + 3 files changed, 24 insertions(+) create mode 160000 build/PSRepositoryReleaseManager diff --git a/.gitmodules b/.gitmodules index 8e5a555..b54ec7b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "build/PSModulePublisher"] path = build/PSModulePublisher url = https://github.com/theohbrothers/PSModulePublisher.git +[submodule "build/PSRepositoryReleaseManager"] + path = build/PSRepositoryReleaseManager + url = https://github.com/theohbrothers/PSRepositoryReleaseManager.git diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b9be8de..d4920ec 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -18,6 +18,11 @@ resources: name: theohbrothers/PSModulePublisher endpoint: theohbrothers # Check for your 'Type: Github' connection under 'Project Settings' > 'Service connections' ref: refs/tags/v0.3.2 + - repository: PSRepositoryReleaseManager + type: github + name: theohbrothers/PSRepositoryReleaseManager + endpoint: theohbrothers + ref: refs/tags/v0.5.2 stages: - stage: build_test @@ -75,3 +80,18 @@ stages: - checkout: self submodules: recursive - template: templates/azure-pipelines/entrypoint/windows/powershell/continuous-build.yml@PSModulePublisher + - template: templates/azure-pipelines/entrypoint/windows/powershell/publish.yml@PSModulePublisher +- stage: release + displayName: Release + dependsOn: publish + jobs: + - job: linux_container + displayName: '[Linux] [Container] PowerShell Core' + pool: + vmImage: ubuntu-18.04 + container: joeltimothyoh/powershell:6.1.0-ubuntu-18.04-git + steps: + - checkout: self + submodules: recursive + - template: templates/azure-pipelines/entrypoint/generate.yml@PSRepositoryReleaseManager + - template: templates/azure-pipelines/entrypoint/release.yml@PSRepositoryReleaseManager diff --git a/build/PSRepositoryReleaseManager b/build/PSRepositoryReleaseManager new file mode 160000 index 0000000..f478a7e --- /dev/null +++ b/build/PSRepositoryReleaseManager @@ -0,0 +1 @@ +Subproject commit f478a7e6782741a15026c81243efbc9e8f19037c From ccff531971faa35bb222a4afee9297216462abb7 Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 18:41:49 +0800 Subject: [PATCH 21/22] Rename .ps1 tasks sample file --- .../scheduledtasks/{definition.ps1.sample => tasks.ps1.sample} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/samples/definitions/scheduledtasks/{definition.ps1.sample => tasks.ps1.sample} (100%) diff --git a/docs/samples/definitions/scheduledtasks/definition.ps1.sample b/docs/samples/definitions/scheduledtasks/tasks.ps1.sample similarity index 100% rename from docs/samples/definitions/scheduledtasks/definition.ps1.sample rename to docs/samples/definitions/scheduledtasks/tasks.ps1.sample From 85b15e9abf41cb9e3e9c8943598c620746a69055 Mon Sep 17 00:00:00 2001 From: Joel Timothy Oh Date: Wed, 20 Nov 2019 19:04:21 +0800 Subject: [PATCH 22/22] Revise sample and test task action arguments --- .../definitions/scheduledtasks/tasks.json.sample | 14 +++++++------- .../definitions/scheduledtasks/tasks.ps1.sample | 14 +++++++------- test/definitions/scheduledtasks/tasks.json | 14 +++++++------- test/definitions/scheduledtasks/tasks.ps1 | 14 +++++++------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/samples/definitions/scheduledtasks/tasks.json.sample b/docs/samples/definitions/scheduledtasks/tasks.json.sample index c38cfc0..e4dbccd 100644 --- a/docs/samples/definitions/scheduledtasks/tasks.json.sample +++ b/docs/samples/definitions/scheduledtasks/tasks.json.sample @@ -20,11 +20,11 @@ "Action": [ { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item $env:TEMP\\$_ }\"" }, { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item $env:TEMP\\$_ }\"" } ], "Settings": { @@ -62,11 +62,11 @@ "Action": [ { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item $env:TEMP\\$_ }\"" }, { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item $env:TEMP\\$_ }\"" } ], "Settings": { @@ -136,15 +136,15 @@ "Action": [ { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item $env:TEMP\\$_ }\"" }, { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item $env:TEMP\\$_ }\"" }, { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.3 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.3 | % { New-Item $env:TEMP\\$_ }\"" } ], "Settings": { diff --git a/docs/samples/definitions/scheduledtasks/tasks.ps1.sample b/docs/samples/definitions/scheduledtasks/tasks.ps1.sample index 0a41d20..7dba66c 100644 --- a/docs/samples/definitions/scheduledtasks/tasks.ps1.sample +++ b/docs/samples/definitions/scheduledtasks/tasks.ps1.sample @@ -51,11 +51,11 @@ Action = @( @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item $env:TEMP\$_ }"' } @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item $env:TEMP\$_ }"' } ) Settings = @{ @@ -100,11 +100,11 @@ Action = @( @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item $env:TEMP\$_ }"' } @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item $env:TEMP\$_ }"' } ) Settings = @{ @@ -215,15 +215,15 @@ Action = @( @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item $env:TEMP\$_ }"' } @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item $env:TEMP\$_ }"' } @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.3 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.3 | % { New-Item $env:TEMP\$_ }"' } ) Settings = @{ diff --git a/test/definitions/scheduledtasks/tasks.json b/test/definitions/scheduledtasks/tasks.json index 517b3a4..f991dd2 100644 --- a/test/definitions/scheduledtasks/tasks.json +++ b/test/definitions/scheduledtasks/tasks.json @@ -20,11 +20,11 @@ "Action": [ { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item $env:TEMP\\$_ }\"" }, { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item $env:TEMP\\$_ }\"" } ], "Settings": { @@ -65,11 +65,11 @@ "Action": [ { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item $env:TEMP\\$_ }\"" }, { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item $env:TEMP\\$_ }\"" } ], "Settings": { @@ -139,15 +139,15 @@ "Action": [ { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.1 | % { New-Item $env:TEMP\\$_ }\"" }, { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.2 | % { New-Item $env:TEMP\\$_ }\"" }, { "Execute": "powershell", - "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.3 | % { New-Item R:\\$_ }\"" + "Argument": "-NonInteractive -NoProfile -NoLogo -Command \"Get-Date -UFormat .%s.3 | % { New-Item $env:TEMP\\$_ }\"" } ], "Settings": { diff --git a/test/definitions/scheduledtasks/tasks.ps1 b/test/definitions/scheduledtasks/tasks.ps1 index 2218fd9..77f500c 100644 --- a/test/definitions/scheduledtasks/tasks.ps1 +++ b/test/definitions/scheduledtasks/tasks.ps1 @@ -51,11 +51,11 @@ Action = @( @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item $env:TEMP\$_ }"' } @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item $env:TEMP\$_ }"' } ) Settings = @{ @@ -100,11 +100,11 @@ Action = @( @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item $env:TEMP\$_ }"' } @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item $env:TEMP\$_ }"' } ) Settings = @{ @@ -215,15 +215,15 @@ Action = @( @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.1 | % { New-Item $env:TEMP\$_ }"' } @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.2 | % { New-Item $env:TEMP\$_ }"' } @{ Execute = 'powershell' - Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.3 | % { New-Item R:\$_ }"' + Argument = '-NonInteractive -NoProfile -NoLogo -Command "Get-Date -UFormat .%s.3 | % { New-Item $env:TEMP\$_ }"' } ) Settings = @{