2016-04-27 17 views
1

概要: 私は、WMIを介してSCCM内の新しいアプリケーション要求を照会するために使用しているスクリプトがあります。このスクリプトは、PowerShellコンソール内で手動で起動した場合(完全に動作するかどうかは関係ありません)、完全に動作します。私はタスクスケジューラを介してスクリプトを実行する必要があります。現在、管理者の資格情報で実行するように設定されており、「最高の権限で実行する」チェックボックスがオンになっています。WindowsタスクスケジューラからPowerShellスクリプトが正しく動作しない

問題: Windows Server 2008 R2のタスクスケジューラから正しく実行されません。エラーが報告されていない(タスクスケジューラが0のエラーコードを返します)が、それは読み込みラインを過ぎて続行していないようです。ここで

$GetAppRequest = Get-WmiObject -Class SMS_UserApplicationRequest -Namespace root/SMS/site_$SiteCode | Where-Object {$_.CurrentState -like "1"} | ForEach-Object { 

がいっぱいスクリプトです:

#Hard-coded variables 
$SiteCode = "MySiteCode" 
$ComputerName = "My-SCCM-Server" 
$GUIDFilePath = "C:\Scripts\SCCM\GUIDList.txt" 
$FilePath = "C:\Scripts\SCCM" 
$smtpServers = "smtp1.domainname.com","smtp2.domainname.com" 
$reliableSmtpServer = $null 
$logpath = "C:\Scripts\SCCM\RequestLog.txt" 

#logging functionality 
function log($message, $type){ 
    $date = get-date 
    $string = "$date $type : $message" | Out-File $logpath -Append 
} 

#does log exist? 
if (gi -Path $logpath -ErrorAction SilentlyContinue){ 
    #yep, the log exists! 
    $logContent = cat $logpath 
    log -message "Script called and log opened for writing." -type "Info" 
} else { 
    #nope, the log doesn't exist, let's make one. 
    write "Can't find log file, creating a new one." 
    $newFileResult = New-Item -Path $logpath -ItemType File -ErrorAction Stop 
    if ($newFileResult.Exists){ 
    log -message "new log file created" -type "Info" 
    } #end if 
} #end else 

#Email variables 
$from = "[email protected]" 
$to = "[email protected]" 
$subject = "New SCCM Application Approval Requests" 

#Determine which SMTP to use. 
$smtpServers | ForEach-Object { 
    if ($reliableSmtpServer -eq $null){ 
    if (Test-Connection -ComputerName $_ -ErrorAction SilentlyContinue){ 
     write "Reliable SMTP server found: $_" 
     $reliableSmtpServer = $_  
    } #end if test-connection 
    } #end if reliableSmtpServer exists 
} #end foreach SMTP server 

if ($reliableSmtpServer){ 
    log -message "Reliable SMTP server found, $reliableSmtpServer" -type "Info" 
} else { 
    log -message "No reliable SMTP server could be found" -type "Error" 
} 

#Get the entries from GUIDList.txt 
if ($GetGUID = Get-Content -Path $GUIDFilePath -ErrorVariable guidReadError { 
    write "Successfully read $GUIDFilePath" 
    log -message "Successfully read $GUIDFilePath" -type "Info" 
} else { 
    Write-Error -Message "Couldn't read GUIDfile..." 
    log -message "Failed to read GUIDFile" -type "Error" 
} 

#Get all Application Requests with a CurrentState of "1" 
log -message 'Attempting to get all Application Requests with a CurrentState of 1' -type "Info" 
$GetAppRequest = Get-WmiObject -Class SMS_UserApplicationRequest -Namespace root/SMS/site_$SiteCode | Where-Object {$_.CurrentState -like "1"} | ForEach-Object { 
    log -message "App found, $_.Application" -type "Info" 
    if ($GetGUID -contains $_.RequestGuid) { 
    Write-Host "Application request $($_.RequestGuid) already present" 
    log -message "Application request $($_.RequestGuid) already present" -type "Info" 
    } else { 
    $appUser = $_.User 
    $appName = $_.Application 
    $appComment = $_.Comments 
    $Body = @" 
    Application request: $appName 
    User: $appUser 

    Comment: $appComment 
    "@ #This row can't contain any blank spaces or tabs 

    log -message "New record found: $appUser, $appName, $appComment" -type "Info" 

    #Email configuration 
    Send-MailMessage -SmtpServer $reliableSmtpServer -From $from -To $to -Subject $subject -Body $body -ErrorVariable mailError 
    if (!($mailError)){ 
    write "Message successfully sent to : $to" 
    log -message "Message successfully sent to : $to" -type "Info" 
    } else { 
    Write-Error -message "Failed to send email!" 
    log -message "Failed to send email!" -type "Error" 
    } #end else 

    #Append the current objects GUID to GUIDList.txt 
    Write "Appending $($_.RequestGUID) to $GUIDFilePath" 
    log -message "Appending $($_.RequestGUID) to $GUIDFilePath" -type "Info" 
$_.RequestGuid | Out-File $GUIDFilePath -Append 

    } #end else statement 
} #end forEach 

#Remove the GUIDList.txt file and re-create it when there's more than 100 entries 
$GUIDCount = $GetGUID.Count 
if ($GUIDCount -gt 100) { 
    log -message "Greater than 100 GUID entries, clearing list." -type "Info" 
    Get-Item $GUIDFilePath | Remove-Item 
    New-Item -Path $FilePath -Name GUIDList.txt -ItemType file 
} 

#Create a new log once the log file exceeds 1000 lines. 
$logCount = $logContent.Count 
if ($logCount -gt 1000) { 
    log -message "Log file is too long, removing log" -type "Warning" 
    Remove-Item $logpath 
} 

ここでは、スケジュールされたタスクのXMLは次のとおりです。そしてHIDD「ユーザーがログオンしている場合にのみ実行されます」と

<?xml version="1.0" encoding="UTF-16"?> 
<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> 
    <RegistrationInfo> 
    <Date>2014-05-09T17:10:48.6636926</Date> 
    <Author>domainname\myUserAccount</Author> 
    <Description>Runs a script located at C:\scripts\SCCM to determine if there are any new application requests and notify IT staff via Email.</Description> 
    </RegistrationInfo> 
    <Triggers> 
    <TimeTrigger> 
     <Repetition> 
     <Interval>PT15M</Interval> 
     <StopAtDurationEnd>false</StopAtDurationEnd> 
     </Repetition> 
     <StartBoundary>2014-05-09T17:12:04</StartBoundary> 
     <ExecutionTimeLimit>PT1H</ExecutionTimeLimit> 
     <Enabled>true</Enabled> 
    </TimeTrigger> 
    </Triggers> 
    <Principals> 
    <Principal id="Author"> 
     <UserId>domain\AdminAccount</UserId> 
     <LogonType>Password</LogonType> 
     <RunLevel>HighestAvailable</RunLevel> 
    </Principal> 
    </Principals> 
    <Settings> 
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> 
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries> 
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries> 
    <AllowHardTerminate>true</AllowHardTerminate> 
    <StartWhenAvailable>false</StartWhenAvailable> 
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable> 
    <IdleSettings> 
     <StopOnIdleEnd>true</StopOnIdleEnd> 
     <RestartOnIdle>false</RestartOnIdle> 
    </IdleSettings> 
    <AllowStartOnDemand>true</AllowStartOnDemand> 
    <Enabled>true</Enabled> 
    <Hidden>false</Hidden> 
    <RunOnlyIfIdle>false</RunOnlyIfIdle> 
    <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession> 
    <UseUnifiedSchedulingEngine>false</UseUnifiedSchedulingEngine> 
    <WakeToRun>false</WakeToRun> 
    <ExecutionTimeLimit>P3D</ExecutionTimeLimit> 
    <Priority>7</Priority> 
    </Settings> 
    <Actions Context="Author"> 
    <Exec> 
     <Command>powershell.exe</Command> 
     <Arguments>-noprofile -file "C:\scripts\sccm\Notify.ps1"</Arguments> 
    </Exec> 
    </Actions> 
</Task> 
+0

そして、他に提供するソリューションのどれ*私のPSスクリプトが質問を助け*スケジュールされたタスクとして実行されませんか?私は他のものを検索することなく、関連リストの7つの潜在重複を右に数えます。あなたはこれらの他の質問に対する解決策を調査しましたか? –

+0

はい、私はそれらを読んだ。インタラクティブなセッションや標高なしでは呼び出すことができなかったものに関連する傾向があったため、役に立たなかった。私はすでに最高のprivsとadmin credentailsで走っているので、標高を割り引いています。インタラクションセッションに関しては、WMIクエリなので、うまくいくはずです。あなたが役に立つと思うものを見つけたら、それを私の方向に向けるようにしてください。 – Mokilok

+0

例外を捕捉するために 'トラップ 'を追加することをお勧めします。あなたのログ関数の後に 'trap {log -message($ _ | fl * -f | out-string)-type" Exception "}'を追加して、例外がスローされたかどうかログを確認できますか? –

答えて

2

$ GetAppRequest変数にGet-WmiObject ... | Foreach-Object {行の結果を割り当てることを意味しましたか?つまり、その変数を再度使用しないので意図的に見えないその割り当てによってForeach-Objectループの出力がキャッチされているということです。

私は、変数への代入を実行してから、変数をForeach-Objectコマンドレットに個別に渡すことをお勧めします。また、Get-WmiObjecttry{}catch{}構成にラップして、コマンドレットがスローする可能性のあるエラーをキャプチャすることもできます。エラーがキャッチされていることを確認するために、我々は-ErrorAction Stopを設定します。

try { 
    $GetAppRequest = Get-WmiObject -Class SMS_UserApplicationRequest -Namespace root/SMS/site_$SiteCode -ErrorAction Stop 
} 
catch { 
    log -message "Get-WmiObject cmdlet failed" -type "Error" 
    log -message $_.Exception.Message.ToString() -type "Error" 
} 

if(-not $GetAppRequest) { 
    log -message "Failed to retrieve WMI data" -type "Error" 

} elseif(-not ($GetAppRequest = $GetAppRequest | Where-Object {$_.CurrentState -like "1"})) { 
    log -message "No results with CurrentState = 1" -type "Info" 
} 

$GetAppRequest | ForEach-Object { 
    ... 
+0

elseif-testに '-not'がないのですか? –

+0

かなり可能です。私が提出したすべてをテストするのではなく、この "盲目"を書いていました!編集します... –

+0

あなたの提案に従いました@CharlieJoynt。タスクマネージャーからログファイルを実行すると、「WMIデータの取得に失敗しました」というログファイルが表示されるようになりました。なぜこれが起こっているのかまだ分かりません。プロファイル内でユニークなものが真実かもしれないと他の人が言ったことは考えましたが、私はそのサーバー上で$ PROFILEドキュメントを使用していません。また、スケジュールされたタスクの動作に-noprofileスイッチがあっても、同じエラーが表示されます。ユーザープロファイルを読み込む時点が表示されていないため、これをインクルードしました。 – Mokilok

-1

チェックenチェックボックスをオフにします。

+0

あなたはそれが必要と思われる理由を説明していただけますか?自分のユーザーアカウントとは異なる資格情報を使ってサーバー上でスクリプトを実行しています。 – Mokilok

+0

まあ、まれなスクリプトでも同じ問題がありましたが、まだサーバー上のユーザーにログオンして実行しています。たとえ、Adobeのリーダーコマンドラインを使用する.netサービスでは、ログオンしたユーザーが作業する必要があります。だからそれを試して、私たちにフィードバックをお願いします。 –

関連する問題