使用三個參數執行 32 位 PowerShell 腳本的計劃任務
TLDR 版本
我需要在Windows Server 2008 R2中執行一個將三個參數作為計劃任務的 32 位 PowerShell 腳本。該腳本啟動了一個 FileSystemWatcher,所以我需要讓它保持活動狀態,以便它可以繼續獲取新文件。
如果您正在瀏覽,您可能應該查看下面“參數”下的內容。
背景
我創建了一個 PowerShell 腳本,可以在我的 Windows Server 2008 R2 機器上的 x86 PowerShell 控制台上正常執行。它創建一個 FileSystemWatcher,並為文件創建事件註冊一個動作。因為我需要 FileSystemWatcher 繼續觀看,所以我需要 PowerShell 繼續執行,而不是在腳本觸發後立即退出:
該腳本採用三個參數:
- 要觀看的文件夾的路徑
- 文件夾的路徑,它將移動任何新的 .xlsx 文件並根據 .xlsx 文件的內容寫入輸出文本文件。
- 日誌文件的路徑。
不過,我無法讓腳本作為計劃任務正確執行。我認為問題在於我正在使用的論點,但我不知道哪些論點是正確的。
設置
由於我需要腳本在 32 位 PowerShell 中執行,所以我將計劃任務的程序設置為 %SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe。
我已確保在 32 位 PowerShell 中將本地電腦的執行策略設置為 RemoteSigned。
論據
我已經為我的論點嘗試了幾種不同的變體。以下在控制台中執行,但對於Task Scheduler以某種方式失敗:
該任務執行,但它不寫入日誌文件,這表明它可能甚至還沒有啟動 FileSystemWatcher。在任何情況下,它都不會在創建文件時拾取文件:
powershell -Noexit -File "D:\Scripts\myScript.ps1" "\\otherServer\share\folder\subfolder\" "\\someserver.domain.edu\D$\working_directory\" "\\otherServer\share\folder\my_log.txt"
任務以程式碼 0xFFFD0000 退出(參見*Powershell Scheduled Task 的 Last Result of 0xFFFD0000*)。我確信該任務正在作為適當的服務帳戶執行,該服務帳戶可以訪問參數中使用的網路共享。
powershell -Noexit -File 'D:\Scripts\myScript.ps1' '\\otherServer\share\folder\subfolder\' '\\someserver.domain.edu\D$\working_directory\' '\\otherServer\share\folder\my_log.txt'
這些變體甚至在控制台中都不起作用(甚至第一次寫入日誌):
powershell -Noexit -File "D:\Scripts\myScript.ps1" "\\otherServer\share\folder\subfolder\ \\server.domain.edu\D$\working_directory\ \\otherServer\share\folder\my_log.txt" powershell -Noexit -command {"& 'D:\Scripts\myScript.ps1' '\\otherServer\share\folder\subfolder\' '\\server.domain.edu\D$\working_directory\' '\\otherServer\share\folder\my_log.txt'"}
根據Scripting Guys 部落格,我認為我應該嘗試使用
-Command
參數而不是-File
. 這兩個變體在控制台中啟動 File System Watcher 並將相應的消息寫入日誌文件,但它們不會在創建時獲取文件:powershell -Noexit -command "& 'D:\Scripts\myScript.ps1' '\\otherServer\share\folder\subfolder\' '\\server.domain.edu\D$\working_directory\' '\\otherServer\share\folder\my_log.txt'" powershell -Noexit -command "& D:\Scripts\myScript.ps1 \\otherServer\share\folder\subfolder\ \\server.domain.edu\D$\working_directory\ \\otherServer\share\folder\my_log.txt"
程式碼
因為腳本在控制台中工作,我很確定問題不在於程式碼本身。不過,對於那些除非看到程式碼才會滿意的人來說,這裡有一些來自腳本本身的相關部分。:)
創建 FileSystemWatcher
Function startWatcher ($onFolder) { try { #Create a file watcher $filter = "*.xlsx" $fsWatcher = New-Object IO.FileSystemWatcher $onFolder, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} $fileWatcherStartDate = (Get-Date -format M.d.yyyy.HH.mm.ss).Tostring() log($fileWatcherStartDate) log "Started file system watcher on $onFolder for $filter files.`r`n" return $fsWatcher } catch { handleError("Error starting file system watcher") } }
註冊創建事件
Function registerCreationEvent ($watcher) { log "Attempting to register creation event..." try { Register-ObjectEvent $watcher Created -SourceIdentifier FileCreated -Action { try { #Code to read from Excel file, create an output text file from the #content, and move both to the specified working directory. } catch { handleError("Performing main action on individual file.") } } log "Event creation registered." } catch { handleError("Error registering creation event") } }
喬治,我想我明白了!
最終,我恢復到最初在 Console 中執行它的方式(即使用dot-sourcing),但在前面添加了 -Noexit 標誌:
程序:
%SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe
論據:
-Noexit . D:\Scripts\myScript.ps1 \\otherserver\share\folder\subfolder\ \\server.domain.edu\D$\working_dir\ \\otherserver\share\folder\my_log.txt