Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scheduled Task for PowerShell Script with String Array Parameter

I've created a PowerShell script that runs perfectly from the Management Shell. I'm trying to get it setup to work in a scheduled task in Windows Server 2008 R2 and am unsure how to pass the parameters for my string array parameter.

Here is the relevant portion of my script:

[CmdletBinding()]
param(
    [Parameter(Mandatory=$true)]
    [String]
        $BaseDirectory,
    [String]
        $BackupMethod = "Full",
    [Int]
        $RemoveOlderThanDays = 0,
    [String]
        $LogDirectory,
    [Int]
        $LogKeepDays = 7,
    [String[]]
        $AdditionalDirectories
)

if ($AdditionalDirectories -and $AdditionalDirectories.Count -gt 0) {
    Write-Host "  Additional Directories to be included:" -ForegroundColor Green
    $AdditionalDirectories | ForEach-Object {
        Write-Host "     $_" -foregroundcolor green
    }
}

The parameter giving the trouble is that last one, $AdditionalDirectories.

From the Shell:

If I run the script from the Management Shell like this, it works perfectly:

.\FarmBackup.ps1 \\SomeServer\Backups Full 0 D:\Logs\Backups 0 "D:\Documents\PowerShell Scripts","D:\SomeFolder"

Result:

   Additional Directories to be included:
      D:/Documents/PowerShell Scripts
      D:/SomeFolder

From Scheduled Task:

Action: Start a program

Program/script: PowerShell.exe

Arguments: -File "D:\Documents\PowerShell Scripts\FarmBackup.ps1" \\SomeServer\Backups Full 0 D:\Logs\Backups 0 "D:\Documents\PowerShell Scripts","D:\SomeFolder"

Result: (From Log File)

  Additional Directories to be included:
     D:\Documents\PowerShell Scripts,D:\SomeFolder

I've tried a couple of different methods for those parameters but I can't seem to get them to be seen as 2 separate strings in the string array. I'm hardcoding them for now, but it seems like there must be a way to make this work since it's totally valid when run from the shell.

like image 863
theChrisKent Avatar asked Oct 02 '12 14:10

theChrisKent


2 Answers

Try using the -Command switch instead of the -File switch, and then use the invocation operator '&'. Here is a link to an example of doing this with scheduled tasks:

http://blogs.technet.com/b/heyscriptingguy/archive/2011/01/12/schedule-powershell-scripts-that-require-input-values.aspx

Something like:

-Command "& 'D:\Documents\PowerShell Scripts\FarmBackup.ps1' '\\SomeServer\Backups' 'Full' 0 'D:\Logs\Backups' 0 'D:\Documents\PowerShell Scripts','D:\SomeFolder'"

I tested this solution by creating a script with the contents:

param([string[]] $x)
Write-Host $x.Count

Then called it in the following two ways:

powershell -File ".\TestScript.ps1" "what1,what2"

with result : 1

and

powershell -Command "& .\TestScript.ps1 what1,what2"

with result: 2

like image 149
dugas Avatar answered Nov 15 '22 04:11

dugas


Another option, when the options get too complex and you're tired of fiddling with quotes, backticks, etc is to use the underused -EncodedCommand parameter on PowerShell.exe e.g.:

C:\PS> $cmd = "c:\temp\foo.ps1 'D:\Documents\PowerShell Scripts','D:\SomeFolder'"
C:\PS> $cmd
c:\temp\foo.ps1 'D:\Documents\PowerShell Scripts','D:\SomeFolder'
C:\PS> $bytes = [Text.Encoding]::Unicode.GetBytes($cmd)
C:\PS> $encodedCmd = [Convert]::ToBase64String($bytes)
C:\PS> $encodedCmd
YwA6AFwAdABlAG0AcABcAGYAbwBvAC4AcABzADEAIAAnAEQAOgBcAEQAbwBjAHUAbQBlAG4AdABzAFwAUABvAHcAZQByAFMAaABlAGwAbAAgAFMAYwByAGkAcAB0AHMAJwAsACcARAA6AFwAUwBvAG0AZQBGAG8AbABkAGUAcgAnAA==
C:\PS> powershell.exe -encodedCommand YwA6AFwAdABlAG0AcABcAGYAbwBvAC4AcABzADEAIAAnAEQAOgBcAEQAbwBjAHUAbQBlAG4AdABzAFwAUABvAHcAZQByAFMAaABlAGwAbAAgAFMAYwByAGkAcAB0AHMAJwAsACcARAA6AFwAUwBvAG0AZQBGAG8AbABkAGUAcgAnAA==
param1[0] is D:\Documents\PowerShell Scripts
param1[1] is D:\SomeFolder

Admittedly, not something that would be exactly readable/understandable by someone else. :-) You'd have to doc the command in the description of the scheduled task.

like image 28
Keith Hill Avatar answered Nov 15 '22 03:11

Keith Hill