2017-03-15 2 views
0

私はPowershellの小さなプロジェクトに取り組んでいます。 私の仕事は、メールの添付ファイルからすべてのファイルを収集し、すべての.pdfファイルを1つにマージし、生成したファイルをメールに送信するスクリプトを作成することでした。
スクリプトはPowershell ISEで完全に正常に動作しますが、タスクスケジューラから実行しようとすると、マージされた.pdfファイルが破損しています。
これは初めてのことです。タスクスケジューラは、スクリプトファイルによって生成された破損バージョンを作成します。

これは、すべての重労働ない私のメインのコードです:

############################################################# 
##---------------------------------------------------------## 
##   SCHEDULE SCRIPTS IN WINDOWS TASKS    ## 
##---------------------------------------------------------## 
############################################################# 

##PATH TO CREDENTIAL 
$credpath = "C:\Users\" + $env:UserName + "\Documents\myCred_${env:USERNAME}_${env:COMPUTERNAME}.xml" 

#test variable 
$test = Test-Path $credpath 

##TEST IF CREDENTIAL EXISTS 
if(!$test){ 
## USER PROMPT PSW CREDENTIAL ## 
    $cred = Get-Credential 

    #save credential in documents 
    $cred | Export-CliXml -Path $credpath 
} 

$taskName = "ManageEmailAttachments" 
$taskExists = Get-ScheduledTask | Where-Object {$_.TaskName -like $taskName } 

if($taskExists) 
{ 
    Get-ScheduledJob ManageEmailAttachments 
    Unregister-ScheduledJob ManageEmailAttachments 
    $wshell = New-Object -ComObject Wscript.Shell 
    $wshell.Popup("Task successfully deleted, run the script again to schedule the task",0,"Done",0x0) 
} 
else 
{ 
    $tt = Get-Date 
    $tt = $tt.AddMinutes(1) 
    $testtime = $tt.ToString("HH:mm:ss") 

    #set trigger 
    $trigger = New-JobTrigger -Daily -At "1:00" 
    $testtrigger = New-JobTrigger -Daily -At $testtime 

    #path to the scripts 
    $scriptPath = $PSScriptRoot + "\wps_manage_pdf_attachments.ps1" 


    #options(optional) 
    $option = New-ScheduledJobOption -WakeToRun: $true 

    #create a new task 
    Register-ScheduledJob -Name ManageEmailAttachments -FilePath $scriptPath -Trigger $testtrigger -ScheduledJobOption $option 
} 

:私は新しいタスクを作成し、私は別のスクリプトファイルで実行するコードのこの部分で

function getAttachments 
    { 
    ######################################################### 
    ##-----------------------------------------------------## 
    ##    GET ATTACHMENTS      ## 
    ##-----------------------------------------------------## 
    ######################################################### 

    ##PATH TO CREDENTIAL 
    $credpath = "C:\Users\" + $env:UserName + "\Documents\myCred_${env:USERNAME}_${env:COMPUTERNAME}.xml" 

    #test variable 
    $test = Test-Path $credpath 

    ##TEST IF CREDENTIAL EXISTS 
    if(!$test){ 
    ## USER PROMPT PSW CREDENTIAL ## 
     $cred = Get-Credential 

     #save credential in documents 
     $cred | Export-CliXml -Path $credpath 
    }else{ 
    ##READ USER CREDENTIAL FROM FILE 
     $cred = Import-CliXml -Path $credpath 
    } 

    ##url and date variables 
    $url = "https://outlook.office365.com/api/v1.0/me/messages" 

    $d = [DateTime]::Today.AddDays(-1) 
    $global:date = $d.ToString("yyyy-MM-dd") 

    ## Get all messages that have attachments where received date is greater than $date 
    $messageQuery = "" + $url + "?`$select=Id&`$filter=HasAttachments eq true and DateTimeReceived ge " + $date 
    $messages = Invoke-RestMethod $messageQuery -Credential $cred 

    ## Loop through each results 
    foreach ($message in $messages.value) 
    { 
     # get attachments and save to file system 
     $query = $url + "/" + $message.Id + "/attachments" 
     $attachments = Invoke-RestMethod $query -Credential $cred 

     # in case of multiple attachments in email 
     foreach ($attachment in $attachments.value) 
     { 
      Write-Host “Found File :- ” $attachment.Name 
      $path = "c:\Attachments\" + $attachment.Name 

      $Content = [System.Convert]::FromBase64String($attachment.ContentBytes) 
      Set-Content -Path $path -Value $Content -Encoding Byte 
     } 
    } 
} 

    function sendAttachments 
    { 
    ############################################################# 
    ##---------------------------------------------------------## 
    ##   SEND ATTACHMENTS AND DELETE FILES    ## 
    ##---------------------------------------------------------## 
    ############################################################# 

    #Connection Details 

    #PATH TO CREDENTIAL 
    $credpath = "C:\Users\" + $env:UserName + "\Documents\myCred_${env:USERNAME}_${env:COMPUTERNAME}.xml" 
    $cred = Import-CliXml -Path $credpath 

    $smtpServer = “ smtp.office365.com” 

    $msg = new-object Net.Mail.MailMessage 

    #Change port number for SSL to 587 
    $smtp = New-Object Net.Mail.SmtpClient($SmtpServer, 25) 

    #Uncomment Next line for SSL 
    $smtp.EnableSsl = $true 

    $smtp.Credentials = $cred 

    $msg.IsBodyHtml = $true 

    #From Address 
    $msg.From = $cred.UserName 
    #To Address, Copy the below line for multiple recipients 
    $msg.To.Add(“[email protected]”) 

    #Message Body 
    $msg.Body=”<h2>Alle attachments samen bevinden zich in de bijlage van did email</h2> <br/><br/>” 

    #Message Subject 
    $msg.Subject = “no-reply: Email met alle attachments” 

    #your file location 
    $files=Get-ChildItem “C:\Attachments\” 

    #attach the right file 
    $file = $global:pname 
    Write-Host “Attaching File :- ” $file 
    $attachment = New-Object System.Net.Mail.Attachment –ArgumentList C:\Attachments\$file 
    $msg.Attachments.Add($attachment) 

    #send email 
    $smtp.Send($msg) 
    $attachment.Dispose(); 
    $msg.Dispose(); 

    #delete the files from the folder 
    Get-ChildItem -Path C:\Attachments -Include * -File -Recurse | foreach { $_.Delete()} 
    } 

function mergePDF 
{ 
############################################################# 
##---------------------------------------------------------## 
##    MERGE ALL PDF FILES      ## 
##---------------------------------------------------------## 
############################################################# 
    $workingDirectory = "C:\Attachments" 
    $itspath = $PSScriptRoot 
    $global:pname = $global:date + "_pdfAttachments.pdf" 
    $pdfs = ls $workingDirectory -recurse | where {-not $_.PSIsContainer -and $_.Extension -imatch "^\.pdf$"}; 

    [void] [System.Reflection.Assembly]::LoadFrom([System.IO.Path]::Combine($itspath, 'itextsharp.dll')); 

    $output = [System.IO.Path]::Combine($workingDirectory, $pname); 
    $fileStream = New-Object System.IO.FileStream($output, [System.IO.FileMode]::OpenOrCreate); 
    $document = New-Object iTextSharp.text.Document; 
    $pdfCopy = New-Object iTextSharp.text.pdf.PdfCopy($document, $fileStream); 
    $document.Open(); 

    foreach ($pdf in $pdfs) { 
     $reader = New-Object iTextSharp.text.pdf.PdfReader($pdf.FullName); 
     [iTextSharp.text.pdf.PdfReader]::unethicalreading = $true 
     $pdfCopy.AddDocument($reader); 
     $reader.Dispose(); 
    } 
    $document.Close() 
    $pdfCopy.Dispose(); 
    $document.Dispose(); 
    $fileStream.Dispose(); 
} 
getAttachments 
Start-Sleep -s 10 
mergePDF 
Start-Sleep -s 10 
sendAttachments 

をスクリプトはPowershellで動作するときにうまくいきます。メールボックスからすべての添付ファイルを取得し、1つの.pdfファイルにマージして、要求されたメールアドレスに送信します。しかし、Windowsのタスクスケジューラでスケジューリングすると、最初のステップはうまくいきますが、マージされると、.pdfファイルは内容なしで破損します。

どのように動作させるのか分かりませんでしたので、フォーラムに質問を投稿しました。 あなたたちはそれを理解する方法を見つけることを願っています。

ありがとうございます

答えて

0

明らかに、問題はメインコードに入れ子になっています。私は使用した:

Try{...} 
Catch{$_ | Out-File C:\errors.txt} 

エラーが何かを見つけるためにmergePDF関数で。私のITextSharp.dllへのパスが間違っているようです。私が使用した$ PSScriptRootは、スクリプトが実際にどこにあるかの代わりに "C:\ windows \ windows32"を示しました。

は、だから私は代わりに何をしたかの%TEMP%にitextsharp.dllをコピーするために、私のバッチファイルで行を追加しました:その後、

xcopy Scripts\itextsharp.dll %Temp% /D >NUL 2>NUL 

としてそこからファイルを読み込む:

$itsPath = [System.IO.Path]::GetTempPath() 

そして、すべてがうまくいくはずです。私はこれが最良の方法ではないことを知っていますが、これをダブルクリックするだけでスクリプトを実行させる前に、このバッチファイルを用意しました。 小さな線を加えても痛いことはありません。

これは、同じ問題を抱えている人に役立つことを願っています。

0

スクリプトのルートディレクトリを取得するには、以下の関数を使用してください。 機能は、Get-ScriptDirectoryを { $呼び出し=(取得-変数MyInvocation -scope 1).Valueの スプリットパス$ Invocation.MyCommand.Path } $は、scriptPath =「(GET-ScriptDirectory)のパスに参加wps_manage_pdf_attachments.ps1 '

+0

私のコードを改善していただきありがとうございますが、これで問題は解決されません。生成されたpdfファイルにはまだ内容がありません – ThizzHead

関連する問題