0

The script below is a part of a bigger project of converting msgs to pdfs. What I'm having problem with implementing is the attachments custom property. I'd like is for it to take custom value based on calculated value based on msg attachments. The MailItem.Attachments.Count will not do. It includes images embeden in the body of message. This can be circumvented with the second snippet. I however cannot combide the two.

Main script:

$o = new-object -comobject outlook.application
$path = "PATH"
cd $path
gc test.csv|Select -skip 2 -First 1|%{$_|Add-Member -MemberType NoteProperty -Name 'BaseName' -Value $_.substring($_.Lastindexof('\')+1).substring(0, $_.substring($_.Lastindexof('\')+1).Lastindexof('.'));
$_|Add-Member -MemberType NoteProperty -Name 'FileName' -Value $_.substring($_.Lastindexof('\')+1);
$_|Add-Member -MemberType NoteProperty -Name 'FullName' -Value $_;
$_|Add-Member -MemberType NoteProperty -Name 'Folder' -Value $_.substring(0, $_.Lastindexof('\'));
$_|Add-Member -MemberType ScriptProperty -Name 'New Loc' -Value {if($msg.Attachments.Count -eq 0){$msgDirectory + '\Converted\'}elseif($msg.Attachments.Count -ge 1){$msgDirectory + '\Converted\' + $msgBaseName + '\'}};





$_|Add-Member -MemberType ScriptProperty -Name 'Attachments' -Value {IF ((SECOND SNIPPET) -gt 0){"YES"}ELSE{"NO}};




$msgBaseName = $_.BaseName
$msgFullname = $_.FullName
$msgDirectory = $_.Folder
$msgName = $_.Filename

$msg = $o.CreateItemFromTemplate($msgFullname)
}

Second part:

$results = 0
$msg.Attachments|%{$att = $_
$attach = $att.FileName; 
$file = 'C:\Users\anowak\Downloads\Script_Test\' + $attach
$file
IF(($msg.HTMLBody) -like "*cid:$attach*"){}else{$results ++} #check if 'attachment' present in the body
$results
Nawad-sama
  • 151
  • 2
  • 12

1 Answers1

0

Apparently this will do the trick.

$o = new-object -comobject outlook.application
$path = "Path"
cd $path

$output = @()

gc test.csv |
  Select -skip 3 -First 1 | 
  % { 

    $_ | Add-Member -MemberType NoteProperty -Name 'BaseName' -Value $_.substring($_.Lastindexof('\') + 1).substring(0, $_.substring($_.Lastindexof('\') + 1).Lastindexof('.'))
    $_ | Add-Member -MemberType NoteProperty -Name 'FileName' -Value $_.substring($_.Lastindexof('\') + 1)
    $_ | Add-Member -MemberType NoteProperty -Name 'FullName' -Value $_
    $_ | Add-Member -MemberType NoteProperty -Name 'Folder' -Value $_.substring(0, $_.Lastindexof('\'))
    $_ | Add-Member -MemberType ScriptProperty -Name 'New Loc' -Value { if ($msg.Attachments.Count -eq 0) { $msgDirectory + '\Converted\' }elseif ($msg.Attachments.Count -ge 1) { $msgDirectory + '\Converted\' + $msgBaseName + '\' } }

    $msgBaseName = $_.BaseName
    $msgFullname = $_.FullName
    $msgDirectory = $_.Folder
    $msgName = $_.Filename

    $msg = $o.CreateItemFromTemplate($msgFullname)

    $results = 0
    $msg.Attachments | 
      % { 
        $att = $_
        $attach = $att.FileName
        $file = 'Path' + $attach
        IF (($msg.HTMLBody) -like "*cid:$attach*") {} else { $results++ } #check if 'attachment' present in the body
        $results
      }
  
    $_ | Add-Member -MemberType ScriptProperty -Name 'Attachments' -Value { if ($results -eq 0) { 'NO' } else { 'Yes' } };

    $output += $_ | Select FullName, FileName, "New Loc", Attachments

  }

$output | Out-GridView

To explain what I've done. I placed 'second part' before Add-Member along with COM Object so that calculations can be made. I've tested it and works. The only issue is that I have to restart ISE everytime. Otherwise the $results variable will remain populated and the script will not work as intended.

mklement0
  • 382,024
  • 64
  • 607
  • 775
Nawad-sama
  • 151
  • 2
  • 12
  • As an aside: Extending arrays in a loop with `+=` is inefficient, because a _new_ array must be created behind the scenes _in every iteration_, given that arrays are of fixed size; a much more efficient approach is to let PowerShell itself collect the outputs in an array: `[array] $outputs = gc test.csv ...` - see [this answer](https://stackoverflow.com/a/60708579/45375). In case you need to create arrays manually, e.g. to create _multiple_ ones, use an efficiently extensible list type - see [here](https://stackoverflow.com/a/60029146/45375). – mklement0 Oct 10 '22 at 12:38
  • As an aside: The PowerShell ISE is [no longer actively developed](https://docs.microsoft.com/en-us/powershell/scripting/components/ise/introducing-the-windows-powershell-ise#support) and [there are reasons not to use it](https://stackoverflow.com/a/57134096/45375) (bottom section), notably not being able to run PowerShell (Core) 6+. The actively developed, cross-platform editor that offers the best PowerShell development experience is [Visual Studio Code](https://code.visualstudio.com/) with its [PowerShell extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell). – mklement0 Oct 10 '22 at 12:38
  • It's great that you're sharing a solution, but the formatting of your code makes it difficult to understand what's going on. Consider using proper indentation and inserting empty lines to improve the structure. – mklement0 Oct 10 '22 at 12:40
  • Those are good arguments, but... I cannot use enything above 5.1.19041.1682. Company device - no admin rights to update. Same thing fo VS. I will see the post you mentioned though. Thanks – Nawad-sama Oct 10 '22 at 12:42
  • Glad to hear it. It is possible to install Visual Studio Code without admin rights. – mklement0 Oct 10 '22 at 12:44
  • Not in this case. Any installation has to be run via admin account. It would have to be a portable version. – Nawad-sama Oct 10 '22 at 12:59
  • @mklement0 believe me I tried, but it comes out even more garbled. Any pointers? – Nawad-sama Oct 10 '22 at 13:00
  • I see - so there's some sort of watchdog software that intercepts attempts to run user-level installers? As for the ISE problem: of course, you can initialize `$results` at the start of your script to prevent lingering values, but it's hard to do that consistently, for all variables that may be affected. As for formatting: I gave it a shot - see if it works for you. – mklement0 Oct 10 '22 at 16:38
  • 1
    @mklement0 I belive that it's the domain user settings that prevent instalation, but I'm no expert in this regard. As for using `[system.colletions.arraylist]`, I measured the script with the original `+=` solution and `arraylist` object. The difference of 7 miliseconds may seem insignificant for small number of files (there are 6 in test group) but it would pile up. Thanks. Your formating made my code look more readable. Thanks again. – Nawad-sama Oct 11 '22 at 06:35