Сценарий Powershell 2.0 запускается в cmd.exe, но не в планировщике задач - PullRequest
4 голосов
/ 27 октября 2011

Я недавно установил Powershell 2.0 на свой сервер SBS 2008 SP2 и считаю, что он работает хорошо. При входе на сервер обе программы Windows Powershell (x86) и Windows Powershell имеют Get-ExecutionPolicy , установленную на RemoteSigned . Get-Host обоих Poweshell показывает версию как 2.0 .

Сценарий сохраняется на C: \ Script \ Powershell \ Сервера и называется TaskScheduler_Get_SFTP_Files.ps1

Если я запускаю из cmd.exe в C: \ команду Powershell C: \ Script \ Powershell \ TaskScheduler_Get_SFTP_Files.ps1 , то Powershell подключается к учетной записи FTP с помощью различных команд загружается из PuTTY , переименовывает загруженные файлы и сохраняет их в своем местоположении. На протяжении всего моего скрипта у меня есть различные команды Write-Output . Таким образом, когда я запускаю скрипт вручную, я вижу в оболочке cmd, что происходит. Это прекрасно работает, вызывая cmd.exe, и я вижу окончательный каталог с загруженными файлами.

Планировщик заданий , с другой стороны, кажется, нуждаются в сладких словах ободрения для выполнения работы (в настоящее время за пределами моего словарного запаса). В Планировщике заданий я настроил задание со следующей спецификацией (скопировано из экспорта XML) и обращаю ваше внимание на то, как я вызываю Powershell с аргументом:

    <Principal id="Author">
       <UserId>WOODBRIDGE\ADMIN</UserId>
       <LogonType>Password</LogonType>
       <RunLevel>HighestAvailable</RunLevel>
     </Principal>
   <Settings>
     <IdleSettings>
       <Duration>PT10M</Duration>
       <WaitTimeout>PT1H</WaitTimeout>
       <StopOnIdleEnd>true</StopOnIdleEnd>
       <RestartOnIdle>false</RestartOnIdle>
     </IdleSettings>
     <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
     <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
     <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
     <AllowHardTerminate>true</AllowHardTerminate>
     <StartWhenAvailable>false</StartWhenAvailable>
     <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
     <AllowStartOnDemand>true</AllowStartOnDemand>
     <Enabled>true</Enabled>
     <Hidden>false</Hidden>
     <RunOnlyIfIdle>false</RunOnlyIfIdle>
     <WakeToRun>true</WakeToRun>
     <ExecutionTimeLimit>PT4H</ExecutionTimeLimit>
     <Priority>7</Priority>
   </Settings>
   <Actions Context="Author">
     <Exec>
       <Command>Powershell</Command>
       <Arguments>-NoProfile -File C:\Script\Powershell\TaskScheduler_Get_SFTP_Files.ps1</Arguments>
     </Exec>
   </Actions>

При просмотре истории задачи одним из элементов является EventID 201 с общим комментарием "Планировщик задач успешно завершил задачу" \ XXX \ YYYYYYYYYYYYYYYYYYYYY ", экземпляр" {23dee164-ea4b -4ed5-ba48-19f07bb83f3e} ", действие" C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ Powershell.EXE "с кодом возврата 0 ."

Любая помощь будет оценена?

Ответы [ 3 ]

1 голос
/ 27 октября 2011
Решение

@ nimizen будет работать, но в PowerShell 2.0 есть несколько более простой способ запуска файлов сценариев:

-NoLogo -File C:\Script\Powershell\TaskScheduler_Get_SFTP_Files.ps1

Возможность использования параметра -NoProfile также зависит от того, загружает ли ваш профиль модулиили оснастки, необходимые для сценария.

1 голос
/ 31 октября 2011

Это был странный вопрос, от которого я до конца не дошел. Спасибо всем респондентам за вклад. Я изменил аргументы в планировщике задач, чтобы они показывали -NoLogo -NoProfile -File ...

Единственная проблема заключается в том, что мой скрипт Powershell не будет выполнять полезный сегмент, который создал новый каталог, загружать файлы FTP и переименовывать их. В начале сценария у меня была команда dir> C: \ Temp \ Dir.txt, которая должна была быть выполнена (это просто для того, чтобы увидеть, действительно ли планировщик заданий запускает задачу), однако фактическая часть для меня интересна. (бит, который загружал и обрабатывал информацию с FTP, не работал.

В планировщике задач мне пришлось изменить параметры безопасности на «Запускать только когда пользователь вошел в систему», а пользователь был администратором для SBS 2008. Если я попытаюсь оставить задачу как «Запускать ли пользователь вошли в систему или нет »и поставили галочку« Запускать с самыми высокими привилегиями », запускается только та часть, которая принимает копию каталога.

К вашему сведению, я программирую в Powershell только неделю и не очень удобен с регулярными выражениями, поэтому мой код довольно неэффективен (кто-то может определить, почему не выполняется часть кода на FTP)? На данный момент я оставлю планировщик задач «Запускать только когда пользователь вошел в систему», так как по крайней мере таким образом файлы загружаются и обрабатываются.

Спасибо всем. (Извините за публикацию моего ужасного кода, но для кого-то может быть очевидно, что часть, находящаяся за пределами dir> C: \ Scripts \ Powershell \ dir.txt, не запускается, когда используется планировщик задач «Запускать, вошел ли пользователь в систему или нет» и это может помочь людям с очень простым инелегенским и небезопасным сценарием SFTP загружать файлы?)

# -----------------------------------------------------------------------------
clear
dir > C:\Scripts\Powershell\dir.txt
$ErrorActionPreference = 'SilentlyContinue'
# Do not change the MM to mm as it will NOT return the month!
[string]$TodayDate = Get-Date -Format "yyyyMMdd"
[string]$DayName = Get-Date -Format "dddd"


# -----------------------------------------------------------------------------
# Define the environment variables
$ScriptPath = 'W:\IT\Utilities\PuTTY\'
$DestFolder = 'W:\BBBB\Statements\'
$BBBB_acc = 'myAccount@BBBB.com:outgoing/*.*'
$BBBB_pwd = 'myPassword'
$DoDelete = $false
$Ext = @(".csv", ".pdf")
$ExpectedFileNames = @("marginreport", "XXX14444", "XXX1cash", "XXX1money", "XXX1opnpos", "XXX1trades", "XXX1_an", "XXX1_ds", "XXX1_ep", "XXX1_ms")
$ReplacedFileNames = @("Margin_MAC", "Call_Interest", "XXX_Cash", "XXX_Money", "XXX_Open", "XXX_Trades", "Margin_Analysis", "FFO", "XXX_EP", "Margin_Summary")


$DoDownload = $true
IF ($DayName -eq "Saturday") {$DoDownload = $false}
IF ($DayName -eq "Sunday") {$DoDownload = $false}


 # -----------------------------------------------------------------------------
if ($DoDownload) {
    # Make sure the destination directories exist
    IF (!(Test-Path $DestFolder)){
        New-Item -type directory -path $DestFolder
        # Write-Output ('Created target directory: ' + $DestFolder)
        }

    $TodaysDestFolder = $DestFolder + $TodayDate    
    IF (!(Test-Path $TodaysDestFolder)){
        New-Item -type directory -path $TodaysDestFolder
        # Write-Output ('Created todays target directory: ' + $TodaysDestFolder)
        }


    # -----------------------------------------------------------------------------
    # SFTP todays Files
    # Old method of calling calling a batch file .\Download_BBBB_Outgoing.bat
    & ($ScriptPath + '\pscp.exe') -sftp -P 22 -pw $BBBB_pwd $BBBB_acc $DestFolder
    # Write-Output ("Finished Downloading Files")


    # -----------------------------------------------------------------------------
    # Create the FTP Delete Script, Rename and Move the Files
    # The PuTTY batch files need to be ASCII, Powershell by default may write in UNICODE
    # Write-Output ('Creating Script File for FTP')
    $BBBB_Pattern = '\.(csv|pdf)'
    $BBBB_Script_FileName = "SFTP_BBBB_Delete_Files.txt"
    $BBBB_Script_FullFileName = $DestFolder + "\" + $BBBB_Script_FileName

    # Get-ChildItem $DestFolder -Recurse seems to traverse all subdirectories
    $Count = 0
    "cd outgoing" | Out-File $BBBB_Script_FullFileName -encoding ASCII -force
    Get-ChildItem $DestFolder | Foreach-Object {
        if ($_.Name -match $BBBB_Pattern) {
            # Append the instruction to delete the file to the FTP script
            "del " + $_ | Out-File $BBBB_Script_FullFileName -encoding ASCII -append

            # Find the extension of the file
            $i = 0
            while ((($_.name).ToLower()).IndexOf($Ext[$i]) -eq -1){
                $i++}

            # See if there is a replacement name for the file
            $j = 0
            while ((($_.name).ToLower()).IndexOf($ExpectedFileNames[$j]) -eq -1){            
                $j++}

            # Construct FileName
            $FTPDateStamp = ($_.name).substring(($_.name).length - 14, 14)
            $FTPDateStamp = $FTPDateStamp -replace("\.","")
            $IdxExt = (($_.Name).tolower()).IndexOf($Ext[$i])
            if ($j -eq -1){
                $NewName = ($_.name).substring(0,$IdxExt) + '_20' + $FTPDateStamp + $Ext[$i]
                }
            else {
                $NewName = $ReplacedFileNames[$j] + '_20' + $FTPDateStamp + $Ext[$i]
                }

            Rename-Item ($DestFolder + "\" + $_) -NewName $NewName
            Move-Item ($DestFolder + $NewName) $TodaysDestFolder
            $Count = $Count + 1
            }
        }

    # -----------------------------------------------------------------------------
    # Delete the downloaded files from the SFTP
    # PSFTP will terminate the batch if an error occurs. This can be changed with the -be switch
    # See 6.1.1 of the PuTTY release notes
    if ($DoDelete) {
        if ($Count -gt 0) {
            # Write-Output ('Deleting the downloaded files from SFTP account')
            & ($ScriptPath + '\psftp.exe') -batch myAccount@BBBB.com -pw $BBBB_pwd -P 22 -b $BBBB_Script_FullFileName
            }
        }

    Remove-Item $BBBB_Script_FullFileName
    $ErrorActionPreference = 'Continue'
    # Write-Output ('Script finished to download from BBBB SFTP account')
    }
0 голосов
/ 27 октября 2011

Пожалуйста, попробуйте изменить аргументы вашей команды следующим образом:

-noprofile -nologo -command "&{C:\Script\Powershell\TaskScheduler_Get_SFTP_Files.ps1}"
...