简体   繁体   中英

Powershell 2.0 Script Runs in cmd.exe but not Task Scheduler

I have recently installed Powershell 2.0 onto my SBS 2008 SP2 server and belive it is working well. When logged onto the server, both Windows Powershell (x86) and Windows Powershell programmes have Get-ExecutionPolicy set to RemoteSigned . The Get-Host of both Poweshell shows the version as 2.0 .

The script is saved on the C:\\Script\\Powershell\\ of the Server and is called TaskScheduler_Get_SFTP_Files.ps1

If I run from cmd.exe at C:\\ the command Powershell C:\\Script\\Powershell\\TaskScheduler_Get_SFTP_Files.ps1 , Powershell then connects to the FTP account using various commands downloaded from PuTTY , renames the downloaded files and then saves them to their location. Throughout my scipt, I have various Write-Output commands as that way, when I run the script manually I can see at the cmd shell whats happening. This works fine calling from cmd.exe and I can see the final directory with the downloaded files.

Task Scheduler on the other hand appears to need sweet words of encouragement to do the work (currently beyond my vocabulary). Within Task Scheduler, I have set up a job that has the following specification (copied from the XML export) and draw your attention to how I am calling Powershell with the argument:

    <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>

When looking at the history for the Task, one of the items is an EventID 201 with the General comment being "Task Scheduler successfully completed task "\\XXX\\YYYYYYYYYYYYYYYYYYYYY" , instance "{23dee164-ea4b-4ed5-ba48-19f07bb83f3e}" , action "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\Powershell.EXE" with return code 0 ."

Any help would be appreciated?

@nimizen solution will work but in PowerShell 2.0 there is a slightly easier way to launch script files:

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

Whether or not you also use the -NoProfile option depends on whether your profile loads modules or snapins that the script requires.

This was a strange one which I have not quite got to the bottom of. Thanks to all the respondents for the contributions. I have ammended the arguments in the Task Scheduler to show -NoLogo -NoProfile -File ...

The only problem is that my Powershell sricpt would not execute the useful segment that created the new directory, download the FTP files and rename them. At the begining of the script, I had a dir > C:\\Temp\\Dir.txt command which would execute (this was simply to see whether the Task Scheduler was indeed kicking off the task), however the actual part of intetest to me (the bit that downloaded and processes the information from the FTP did not work.

From within Task Scheduler, I have had to change the security options to "Run only when the user is logged on" with the user being the Administrator for SBS 2008. If I try to keep the task as "Run whether user is logged on or not" and have the checkbox ticked "Run with the heighest privelages", only the part that takes a copy of the directory runs.

FYI, I have only been programming in Powershell for a week and am not that comfortable with regular expressions so my code is quite inefficient (someone may be able to spot why the FTP part of the code does not run)? For the moment, I will leave the Task Scheduler to "Run only when the user is logged on" as at least this way the files are downloaded and processed.

Thanks all. (Sorry for posting my horrible code, but it may be obvious to someone why the part beyond dir > C:\\Scripts\\Powershell\\dir.txt does not run when Task Scheduler "Run whether user is logged on or not" is used and it may help people with a very basic inelegenat and insecure SFTP script to download files?)

# -----------------------------------------------------------------------------
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')
    }

请尝试如下更改命令参数:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM