Windows-Server-2008-R2

使用三個參數執行 32 位 PowerShell 腳本的計劃任務

  • March 17, 2015

TLDR 版本

我需要在Windows Server 2008 R2中執行一個將三個參數作為計劃任務的 32 位 PowerShell 腳本。該腳本啟動了一個 FileSystemWatcher,所以我需要讓它保持活動狀態,以便它可以繼續獲取新文件。

如果您正在瀏覽,您可能應該查看下面“參數”下的內容。

背景

我創建了一個 PowerShell 腳本,可以在我的 Windows Server 2008 R2 機器上的 x86 PowerShell 控制台上正常執行。它創建一個 FileSystemWatcher,並為文件創建事件註冊一個動作。因為我需要 FileSystemWatcher 繼續觀看,所以我需要 PowerShell 繼續執行,而不是在腳本觸發後立即退出:

該腳本採用三個參數:

  1. 要觀看的文件夾的路徑
  2. 文件夾的路徑,它將移動任何新的 .xlsx 文件並根據 .xlsx 文件的內容寫入輸出文本文件。
  3. 日誌文件的路徑。

不過,我無法讓腳本作為計劃任務正確執行。我認為問題在於我正在使用的論點,但我不知道哪些論點是正確的。

設置

由於我需要腳本在 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

引用自:https://serverfault.com/questions/556569