2017-03-15 29 views
0

我一直在研究Powershell中的一個小項目。 我的任務是創建一個腳本,它將收集郵件附件中的所有文件,將所有.pdf文件合併爲一個文件並將生成的文件發送到我的電子郵件。
該腳本在Powershell ISE中運行得很好,但是當我嘗試從任務計劃程序運行它時,合併的.pdf文件已損壞,並且沒有任何數據。
請記住,我是這個東西的新手。任務計劃程序創建由腳本文件生成的損壞版本

這是做所有繁重的工作我的主要代碼:

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 

在這一段代碼,我在另一個腳本文件運行,我創建了一個新的任務:

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

的腳本在Powershell中運行效果很好時,它會從郵箱中獲取所有附件,將它們合併到1 .pdf文件中並將它們發送到請求的電子郵件地址。但是,當在Windows任務計劃程序中進行計劃時,它會執行第一步,但合併時,.pdf文件會在沒有任何內容的情況下被損壞。

我想不出如何讓它工作,所以我在論壇上發佈了一個問題。 希望你們找到解決的辦法。

在此先感謝

回答

0

顯然這個問題嵌套在主代碼中。我用過:

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

在mergePDF函數中找出錯誤是什麼。似乎我的ITextSharp.dll路徑不正確。我使用的$ PSScriptRoot顯示「C:\ windows \ windows32」,而不是腳本的實際位置。

所以我做了什麼,而不是在我的批處理文件添加一行到itextsharp.dll複製到%TEMP%:

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

,然後從那裏讀取文件:

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

一切正常。我知道這不是最好的方法,但是我之前有過這個批處理文件,只需通過dubbleclicking就可以運行腳本。 因此添加一條小線不會傷害。

我希望這可以幫助任何人有同樣的問題。

0

使用下面的函數獲取腳本根目錄。 功能獲取-ScriptDirectory {$ 調用=(獲取變量MyInvocation -scope 1).value的 分離路徑$ Invocation.MyCommand.Path } $ SCRIPTPATH =聯接路徑(GET-ScriptDirectory)「wps_manage_pdf_attachments.ps1 '

+0

感謝您改進我的代碼,但這並不能解決問題。生成的PDF文件仍然沒有任何內容 – ThizzHead

相關問題