1

Good afternoon, I am very new to Powershell and am trying to achieve the following:

  1. Loop through a folder directory

  2. Set the folder name as a variable

  3. Create a Task

  4. Pass the variable (declared in Step 2) as the required parameter for the -File being called in the Task Action

    Get-ChildItem -Path C:\Users\Paul\Documents\RSYNC -Directory -Recurse |ForEach-Object {
    $FolderName = $_.name
    
    $taskName = 'My Powershell Task_' + $FolderName
    
    # Create Action
    $Action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-File "C:\Users\Paul\Documents\RSYNC\Get-LatestAppLog.ps1" -name "$FolderName"' 
    
    # Create Trigger
    $Trigger = New-ScheduledTaskTrigger -Daily -At 12:35am
    
    # Create Settings
    $Settings = New-ScheduledTaskSettingsSet
    
    # Create Task
    $Task = New-ScheduledTask -Action $Action -Trigger $Trigger -Settings $Settings
    
    # Register Task
    Register-ScheduledTask -TaskName $taskName -InputObject $Task -User 'username' -Password 'password'
    }
    

The tasks are created as desired, however, the problem is that inside the $Action step, instead of passing the folder name inside the $FolderName variable, it is simply passing $FolderName as a string (I hope that makes sense).

How can I correctly pass the folder name to the PowerShell script being called?

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • Swap the double and single quotes. As it is now, `$Foldername` is not expanded, but taken as literal text because the whole thing is between single quotes.` Try `"-File 'C:\Users\Paul\Documents\RSYNC\Get-LatestAppLog.ps1' -name $FolderName" ` – Theo Sep 30 '21 at 12:31
  • `'powershell.exe' -Argument "-File 'C:\Users\Paul\Documents\RSYNC\Get-LatestAppLog.ps1' -name '$FolderName'"` PowerShell doesn't *interpret* nothing inside a **single** quoted string. Double quotes are required for that, so switch the order of quotes, or escape the double quotes inside double quotes. You also don't need to quote `$FolderName` given that it's of type *string*. – Abraham Zinala Sep 30 '21 at 12:31
  • 1
    @Theo: for invocations from _outside_ PowerShell (such as from Task Scheduler) you actually cannot use `'...'`-quoting with _syntactic_ meaning - PowerShell will treat the `'` as a literal part of the file path passed to `-File` and fail. – mklement0 Oct 03 '21 at 20:22

2 Answers2

2
  • Your immediate problem was to expect the reference to variable $FolderName to be expanded (interpolated) inside a verbatim PowerShell string literal, '...':

    • Only "..." strings (double-quoted) perform string interpolation in PowerShell: see this answer for an overview of PowerShell's expandable strings (interpolating strings) and this answer for an overview of PowerShell string literals in general.
  • While swapping the use of quotation marks - using "..." for the outer quoting and '...' for the embedded quoting in order to get interpolation may situationally work - depending on the target program or API - it does not work in the context of Task Scheduler.

    • For command lines in Task Scheduler - and generally on Windows from outside PowerShell - you must use "..." quoting for the embedded strings too, which therefore requires escaping " as `" ("" would work too).

    • The reason is that PowerShell doesn't treat ' characters as having syntactic function when its CLI is called from the outside, such as from Task Scheduler, cmd.exe, or the Windows Run dialog (WinKey-R). For instance, if the path passed to -File were 'C:\Users\Paul\Documents\RSYNC\Get-LatestAppLog.ps1', the ' chars. would be interpreted as part of the path.

Specifically:

$Action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument `
 "-File `"C:\Users\Paul\Documents\RSYNC\Get-LatestAppLog.ps1`" -name `"$FolderName`"" 

Note that you could simplify the quoting with the use of an expandable here-string; the embedded " then do not require escaping:

$Action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument @"
 -File "C:\Users\Paul\Documents\RSYNC\Get-LatestAppLog.ps1" -name "$FolderName"
"@ 
mklement0
  • 382,024
  • 64
  • 607
  • 775
0

Thank you Theo and Abraham Zinala. Both suggested to swap the double and single quotes and that worked perfectly.

  • Do you mean `"-File 'C:\Users\Paul\Documents\RSYNC\Get-LatestAppLog.ps1' -name '$FolderName'"`? I don't think that would work from _outside_ PowerShell, such as from Task Scheduler; from outside PowerShell, quotes that have _syntactic_ function on the command line must be _double_ quotes. – mklement0 Sep 30 '21 at 12:42
  • To put it differently: While your `New-ScheduledTaskAction` call will succeed with embedded `'...'` quoting, the actual later _invocation_ of the command line will fail. – mklement0 Sep 30 '21 at 13:50