PowerShell: Zip up a folder and email it

Posted Wednesday, November 29, 2006 11:46 AM by mhodnick

Here's a quick little PowerShell script you can use in conjunction with Out-Zip to zip up a folder on your hard drive and email it:

$sender = sender@host.com
$recipient = recipient@host.com
$server = mail.host.com
$targetFolder = c:\MyFolder
$file = c:\MyZipFile.zip

if ( [System.IO.File]::Exists($file) )
{
  remove-item -force $file
}

gi $targetFolder | out-zip $file $_
$subject = "Sending a File " + [System.DateTime]::Now
$body = "I'm sending a file!"
$msg = new-object System.Net.Mail.MailMessage $sender, $recipient, $subject, $body
$attachment = new-object System.Net.Mail.Attachment $file
$msg.Attachments.Add($attachment)
$client = new-object System.Net.Mail.SmtpClient $server
$client.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$client.Send($msg)
Filed under:

Comments

# PowerShell News and Examples HQ » Blog Archive » Zip up a folder and email it

# re: PowerShell: Zip up a folder and email it

Tuesday, December 26, 2006 8:13 AM by Rich Whiting

Mike,

Are you sure your zip-email script works?  I have added it to my profile as follows (where <???> represents my company server, hidden here for privacy/security reasons):

function test-it {
$sender = rwhiting@<mycompanyserver>.com
$recipient = rwhiting@<mycompanyserver>.com
$server = exchange2.<mycompanyserver>.com
$targetFolder = c:\MyFolder
$file = c:\MyZipFile.zip

if ( [System.IO.File]::Exists($file) ) {
 remove-item -force $file
}

gi $targetFolder | out-zip $file $_
$subject = "Sending a File " + [System.DateTime]::Now
$body = "I'm sending a file!"
$msg = new-object System.Net.Mail.MailMessage $sender, $recipient, $subject, $body
$attachment = new-object System.Net.Mail.Attachment $file
$msg.Attachments.Add($attachment)
$client = new-object System.Net.Mail.SmtpClient $server
$client.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$client.Send($msg)
}

function out-zip {
$path = $args[0]
$files = $input

if (-not $path.EndsWith('.zip')) {$path += '.zip'}

if (-not (test-path $path)) {
 set-content $path ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
}

$zipfile = (new-object -com shell.application).NameSpace($path)
$files | foreach {$zipfile.CopyHere($_.fullname) }
}

When I execute "test-it" within PowerShell 1.0, I get a series of error messages:


"The term 'rwhiting@<myserver>.com' is not recognized as a cmdlet, function, operable program, or script file. Verify the term and try again."

I get a similar message for "exchange2.<myserver>.com", "rwhiting@<myserver>.com", "MyFolder", and "c:\MyZipFile.zip".

And also (among others): "New-Object: Constructor not found. Cannot find an appropriate constructor for type System.Net.Mail.Attachment."

Am I doing something wrong, even though I basically cut-and-pasted the script?

# re: PowerShell: Zip up a folder and email it

Tuesday, December 26, 2006 8:47 AM by Rich Whiting

Update on above question ...

When I add quotes around each of the literal string values:

    $sender =" rwhiting@<mycompanyserver>.com"
    $recipient =" rwhiting@<mycompanyserver>.com"
    $server =" exchange2.<mycompanyserver>.com"
    $targetFolder = "c:\MyFolder"
    $file =" c:\MyZipFile.zip"

I get fewer error messages, but still this one:

    New-Object: Exception calling ".ctor" with "1" argument(s): "Could not find file 'c:\MyZipFile.zip'."

even though the file DOES exist. Why can't PowerShell see it?

# re: PowerShell: Zip up a folder and email it

Tuesday, December 26, 2006 10:18 AM by Rich Whiting

Further update ...

I had to change this line:

    $client.Credentials = new-object system.net.networkcredential("rwhiting","<mypassword>")

Now the script works fine when I enter it INTERACTIVELY, LINE-BY-LINE in PowerShell. But when I execute it AS A FUNCTION, it still does NOT work, but returns the same old error:

    New-Object: Exception calling ".ctor" with "1" argument(s): "Could not find file 'c:\MyZipFile.zip'."

Why does this script work when entered line-by-line interactively in PowerShell, but NOT when run as a function? What am I missing?

Thanks,

# re: PowerShell: Zip up a folder and email it

Tuesday, December 26, 2006 1:27 PM by Rich Whiting

Solution ...

Okay, I figured it out. The line correction is:

    [System.Net.Mail.Attachment] $attachment = new-object System.Net.Mail.Attachment $file

It is necessary to cast the $attachment variable to type System.Net.Mail.Attachment, since new-object (in this instance) returns a REFERENCE to an object of that type, not an ACTUAL OBJECT of the type. But $msg.Attachments.Add($attachment) requires an actual object. Hence the need for the cast.

# re: PowerShell: Zip up a folder and email it

Thursday, December 28, 2006 8:12 AM by mhodnick

heh, glad you figured it out Rich.  Sorry I wasn't able to respond over the holidays.  

# PowerShell Script: Zip up a folder and email it at ps&gt; get-content

# PowerShell Script: Zip up a folder and email it at ps&gt; get-content