Запланированные задачи, созданные с помощью schtasks.exe
, выполняются с рабочим каталогом , установленным на $env:windir\system32
[1] , поэтому, если ваш сценарий не окажется в ..\Execute\execute.ps1
относительно там , ваша команда не будет работать должным образом.
Если вы не хотите жестко закодировать путь сценария непосредственно в команду, создайте команду динамически , разрешив относительный путь к absolute . при назначении на $Argument
:
$Argument = 'powershell.exe -file \"{0}\"' -f (Convert-Path ..\Execute\execute.ps1)
Обратите внимание, что, к сожалению, необходимо скрыть встроенную "
как \"
, которая является давней ошибкой, которая не была исправлена ради обратной совместимости - см. эту проблему с документацией GitHub для фона.
Convert-Path
разрешает относительный путь к абсолютному.
Обратите внимание, что относительный путь должен указывать на существующий файл (или каталог).
Аналогично, относительные пути внутри ваш скрипт будет относительно $env:windir\system32
тоже ; чтобы сделать их относительно директории script , сначала перейдите в каталог вашего скрипта, выполнив Set-Location $PSScriptRoot
в начале вашего скрипта.
Необязательное чтение: Как процитировать команды, запускаемые из запланированной задачи:
Примечание. Практически применяются те же правила , что и при запуске команды из диалогового окна Windows Run (нажмите WinKey + R ), что вас можно использовать для test-drive команду (команду для передачи на schtasks /tr
без внешней кавычки, а не всю командную строку schtasks
), хотя обратите внимание, что рабочий каталог будет домашний каталог пользователя, и что вы не сможете использовать '...'
-квотирование вокруг аргумента -File
CLI PowerShell - см. ниже):
cmd.exe
НЕ задействован во время выполнения, что означает:
Вам не нужно беспокоиться об использовании метасимволов cmd.exe
без двойных кавычек, таких как, например, &
, так что вы можете использовать эти символы даже в одиночных строках в кавычках передан в PowerShell CLI powershell.exe
как (часть) аргумента (ов) -Command
.
И наоборот, перенаправления вывода (например, > c:\path\to\log.txt
) не поддерживаются напрямую .
В контексте вызова интерфейса командной строки PowerShell это означает:
С -File
вы не можете использовать их в командной строке и вместо этого должны выполнять их из в вашего скрипта.
С -Command
, однако, вы можете использовать их, потому что тогда их применяет PowerShell (но учтите, что оператор Windows PowerShell >
создает UTF) -16LE файлов).
(хотя cmd.exe
не задействован) ссылки на переменные окружения , использующие ту же синтаксическую форму, что и в cmd.exe
, расширен (например, %USERNAME%
)
- Предостережение : Вы не можете избежать таких ссылок :
%%
не работает - дополнительный %
просто обрабатывается как литерал, и расширение по-прежнему происходит; например, %%OS%%
приводит к %Windows_NT%
.
^%
(случайно) предотвращает расширение, но сохраняет ^
- ^
не escape ; скорее он «разрушает» имя переменной, и в этом случае токен остается без изменений; например, ^%OS^%
приводит к ^%OS^%
, то есть сохраняется как есть.
Вышеприведенное относится к командам, так как они должны заканчиваться , определенными внутри запланированной задачи, как вы могли бы видеть или определять их в интерактивном режиме в планировщике задач (taskschd.msc
).
Дополнительно , для создания запланированного задания из командной строки / сценария PowerShell / командного файла :
(Вы можете уйти только без цитированияесли команда состоит только из одиночного слова , которое не требует экранирования, например пути к исполняемому файлу, не содержащему пробелов или специальных символов и к которому не передаются аргументы.)
При вызовеschtasks.exe
[2] , процитируйте аргумент /tr
в целом следующим образом :
из PowerShell , используйте "..."
, если вам нужно расширить (строка-интерполировать) командную строку вперед ;в противном случае используйте '...'
.
Важно : необходимость экранирования вложенного "
в качестве \"
применяется в обоих случаях, что в случае внешнего "..."
цитирование означает, что вложенный "
должен быть экранирован как \`"
(sic).
- Удивительно, но
schtasks.exe
распознает внедренное '...'
цитирование и автоматически переводитэто "..."
цитирование - именно поэтому ваша исходная команда "powershell.exe -file '..\Execute\execute.ps1'"
сработала, хотя при прямом вызове PowerShell CLI не поддерживает использование '...'
в сочетании с -File
.
из cmd.exe
(напрямую или из пакетного файла), вы должны использование "..."
.
Примеры PowerShell :
Следующие команды PowerShell создают и выполняют две команды запуска.запланированные задачи с именами test1
и test2
, которые запускаются, когда начинается следующая календарная минута, в контексте вызывающего пользователя, визуально.(После этого вам придется удалить эти задачи вручную.)
Возможно, вам придется подождать до 1 минуты, чтобы увидеть активацию вызова, после чего появится новое окно консоли.для каждой задачи.
# Create sample script test.ps1 in the current dir. that
# echoes its arguments and then waits for a keypress.
'"Hi, $Args."; Read-Host "Press ENTER to exit"' > test.ps1
# Find the start of the next calendar minute.
$nextFullMinute = ([datetime]::Now.AddMinutes(1).TimeOfDay.ToString('hh\:mm'))
# -File example:
# Invoke test.ps1 and pass it 'foo' as an argument.
# Note the escaped embedded "..." quoting around the script path
# and that with -File you can only pass literal arguments at
# invocation time).
schtasks.exe /create /f /tn test1 /sc once /st $nextFullMinute `
/tr "powershell -File \`"$PWD/test.ps1\`" foo" #`# (dummy comment to fix broken syntax highlighting)
# -Command example:
# Invoke test.ps1 and pass it $env:USERNAME as an argument.
# Note the '...' around the script path and the need to invoke it with
# &, as well as the ` before $env:USERNAME to prevent its premature expansion.
schtasks.exe /create /f /tn test2 /sc once /st $nextFullMinute `
/tr "powershell -Command & '$PWD/test.ps1' `$env:USERNAME"
"Tasks will execute at ${nextFullMinute}:00"
[1] Обратите внимание, что графический интерфейс планировщика заданий позволяет настраивать рабочий каталог, но эта функция недоступнас помощью утилиты schtasks.exe
.
[2] То же самое относится к значениям, передаваемым параметру -Argument
командлета New-ScheduledTaskAction
PowerShell, хотя следует учитывать, что имя / путь к исполняемому файлутам указывается отдельно через параметр -Execute
.
Для сравнения: командлет Register-ScheduledJob
для создания запланированных PowerShell заданий принимает блок сценариев в качестве команды для запуска,который устраняет головную боль цитирования.