2017-03-15 84 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

相关问题