AD Photo (thumbnailphoto)

Outlook 2010 (with Exchange 2010) will use the thumbnailphoto AD Attribute to display images for user accounts. This Attribute is limited to a 10k file.

$UserDN = $UserName.DN $jpegFile = gci "C:\Users\Kevin\desktop\Smile.jpg" $FileData=([byte[]]$(get-content -path $jpegFile.FullName -encoding byte -readcount 0)) Set-QADUser -Identity "$UserDN" -ObjectAttributes @{thumbnailphoto=$FileData} -credential $Cred

Notes

http://www.arricc.net/active-directory-photos-sharepoint.php

http://blogs.technet.com/ilvancri/archive/2010/01/08/follow-up-import-recipientdataproperty.aspx

http://social.technet.microsoft.com/Forums/en/ITCG/thread/403cda19-7a63-4d95-a273-8f7885e836cd

 

Image Manipulation in Powershell

Nice article on image manipulation I need to play with this some more.

$image = New-Object -ComObject Wia.ImageFile             $image.LoadFile("$pwd\try.jpg")             $image.Width, $image.Height

http://blogs.msdn.com/b/powershell/archive/2009/03/31/image-manipulation-in-powershell.aspx

Ugly test tool for images

I made this just playing arround, I may do some work to improve it sometime in the future.

Bulk Photo Import

Quick tool i made to import a big batch of photos

                                                                                  

######################################################################## # Code Generated By: SAPIEN Technologies, Inc., PrimalForms 2009 v1.1.10.0 # Generated On: 11/18/2010 3:28 PM # Generated By: Kevin Curran # Organization: Disorganized ########################################################################  #---------------------------------------------- #region Application Functions #----------------------------------------------  function OnApplicationLoad { #Note: This function runs before the form is created #Note: To get the script directory in the Packager use: Split-Path $hostinvocation.MyCommand.path #Note: To get the console output in the Packager (Windows Mode) use: $ConsoleOutput (Type: System.Collections.ArrayList) #Important: Form controls cannot be accessed in this function #TODO: Add snapins and custom code to validate the application load # IF (Get-PSSnapin | where {$_.name -eq "quest.activeroles.admanagement"})  #   {write-host "Quest Active Roles snapin already loaded"} # Else # {add-PSSnapin  quest.activeroles.admanagement} return $true #return true for success or false for failure }  function OnApplicationExit { #Note: This function runs after the form is closed #TODO: Add custom code to clean up and unload snapins when the application exits $script:ExitCode = 0 #Set the exit code for the Packager }  #endregion  #---------------------------------------------- # Generated Form Function #---------------------------------------------- function GenerateForm {  #---------------------------------------------- #region Import Assemblies #---------------------------------------------- [void][reflection.assembly]::Load("System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") [void][reflection.assembly]::Load("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") [void][reflection.assembly]::Load("System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") #endregion #---------------------------------------------- #region Generated Form Objects #---------------------------------------------- [System.Windows.Forms.Application]::EnableVisualStyles() $frmUserInfoGUI = New-Object System.Windows.Forms.Form $grpSearch = New-Object System.Windows.Forms.GroupBox $btnSearch = New-Object System.Windows.Forms.Button $txtSearchUser = New-Object System.Windows.Forms.TextBox $lblSearchUsername = New-Object System.Windows.Forms.Label $lblMessage = New-Object System.Windows.Forms.Label $btnBrowse = New-Object System.Windows.Forms.Button $txtThumbNailFile = New-Object System.Windows.Forms.TextBox $btnUpdateThumnail = New-Object System.Windows.Forms.Button $picBoxThumbnail = New-Object System.Windows.Forms.PictureBox $lblThumbnailPhoto = New-Object System.Windows.Forms.Label $btnCred = New-Object System.Windows.Forms.Button $btnUpdateEmployeeID = New-Object System.Windows.Forms.Button $txtEmployeeID = New-Object System.Windows.Forms.TextBox $lblEmployeeID = New-Object System.Windows.Forms.Label $txtSAMAccountName = New-Object System.Windows.Forms.TextBox $lblSAMAccountName = New-Object System.Windows.Forms.Label $btnClose = New-Object System.Windows.Forms.Button $txtDomainName = New-Object System.Windows.Forms.TextBox $lblDomainName = New-Object System.Windows.Forms.Label $lblUserName = New-Object System.Windows.Forms.Label $txtUserName = New-Object System.Windows.Forms.TextBox $openfiledialog1 = New-Object System.Windows.Forms.OpenFileDialog $InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState #endregion Generated Form Objects  #---------------------------------------------- # User Generated Script #----------------------------------------------  $handler_textBox3_TextChanged={ #TODO: Place custom script here } $handler_btnClose_Click={ #TODO: Place custom script here $frmUserInfoGUI.Close() } $handler_txtUserName_TextChanged={ #TODO: Place custom script here } $handler_frmUserInfoGUI_Load={ #TODO: Place custom script here $frmUserInfoGUI.WindowState = $InitialFormWindowState $txtUserName.text = $env:USERNAME $txtDomainName.text = $env:USERDOMAIN $dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() $root = $dom.GetDirectoryEntry() $search = [System.DirectoryServices.DirectorySearcher]$root $search.Filter = "(&(objectclass=user)(objectcategory=person)(samAccountName=$env:username))" $result = $search.FindOne() if ($result -ne $null) { $user = $result.GetDirectoryEntry() $txtSAMAccountName.text = $user.Properties["samaccountname"].Value $txtEmployeeID.Text = $user.Properties["EmployeeNumber"].Value $picBoxThumbnail.Image = $user.Properties["thumbnailphoto"].Value } } $handler_btnCred_Click={ #TODO: Place custom script here $Cred=Get-Credential } $handler_btnUpdateEmployeeID_Click={ #TODO: Place custom script here $UserDN = $UserName.DN $EmployeeID = $($txtEmployeeID.Text).trim() #Set-QADUser -Identity "$UserDN" -ObjectAttributes @{EmployeeID="$EmployeeID"} -credential $Cred Write-Host $Cred.UserName } $handler_btnUpdateThumnail_Click={ #TODO: Place custom script here $jpegFile = gci "$($txtThumbNailFile.Text)" $FileData=([byte[]]$(get-content -path $jpegFile.FullName -encoding byte -readcount 0)) $User.put("thumbnailPhoto", $FileData ) $user.setinfo() $lblMessage.Text = "Updating $($user.displayname)`r`n $($error)" # $UserName = Get-QADUser $env:USERNAME -IncludedProperties EmployeeID, thumbnailphoto # $UserDN = $UserName.DN # Set-QADUser -Identity "$UserDN" -ObjectAttributes @{thumbnailphoto=$FileData} -credential $Cred } $handler_btnBrowse_Click={ #TODO: Place custom script here $OpenFileDialog1.ShowDialog() | Out-Null $txtThumbNailFile.Text = $openfiledialog1.FileName #$txtThumbNailFile.text = "foo" } $handler_btnSearch_Click={ #TODO: Place custom script here $search.Filter = "(&(objectclass=user)(objectcategory=person)(samAccountName=$($txtSearchUser.text)))" $result = $search.FindOne() if ($result -ne $null) { $user = $result.GetDirectoryEntry() $txtUserName.text = $user.UserPrincipalName $txtDomainName.text = $user.Domain.Name $txtSAMAccountName.text = $user.Properties["samaccountname"].Value $txtEmployeeID.Text = $user.Properties["EmployeeNumber"].Value $picBoxThumbnail.Image = $user.Properties["thumbnailphoto"].Value } } $handler_btnUpdateEmployeeID_Click={ #TODO: Place custom script here }#end handler_btnUpdateEmployeeID_Click #---------------------------------------------- # Generated Events #---------------------------------------------- $Form_StateCorrection_Load= { #Correct the initial state of the form to prevent the .Net maximized form issue $frmUserInfoGUI.WindowState = $InitialFormWindowState } #---------------------------------------------- #region Generated Form Code #---------------------------------------------- # # frmUserInfoGUI # $frmUserInfoGUI.Controls.Add($grpSearch) $frmUserInfoGUI.Controls.Add($lblMessage) $frmUserInfoGUI.Controls.Add($btnBrowse) $frmUserInfoGUI.Controls.Add($txtThumbNailFile) $frmUserInfoGUI.Controls.Add($btnUpdateThumnail) $frmUserInfoGUI.Controls.Add($picBoxThumbnail) $frmUserInfoGUI.Controls.Add($lblThumbnailPhoto) $frmUserInfoGUI.Controls.Add($btnCred) $frmUserInfoGUI.Controls.Add($btnUpdateEmployeeID) $frmUserInfoGUI.Controls.Add($txtEmployeeID) $frmUserInfoGUI.Controls.Add($lblEmployeeID) $frmUserInfoGUI.Controls.Add($txtSAMAccountName) $frmUserInfoGUI.Controls.Add($lblSAMAccountName) $frmUserInfoGUI.Controls.Add($btnClose) $frmUserInfoGUI.Controls.Add($txtDomainName) $frmUserInfoGUI.Controls.Add($lblDomainName) $frmUserInfoGUI.Controls.Add($lblUserName) $frmUserInfoGUI.Controls.Add($txtUserName) $frmUserInfoGUI.Text = "User Info GUI" $frmUserInfoGUI.Name = "frmUserInfoGUI" $frmUserInfoGUI.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $frmUserInfoGUI.ClientSize = New-Object System.Drawing.Size(425,433) $frmUserInfoGUI.add_Load($handler_frmUserInfoGUI_Load) # # grpSearch # $grpSearch.Controls.Add($btnSearch) $grpSearch.Controls.Add($txtSearchUser) $grpSearch.Controls.Add($lblSearchUsername) $grpSearch.TabIndex = 18 $grpSearch.Size = New-Object System.Drawing.Size(400,55) $grpSearch.Text = "Search" $grpSearch.Location = New-Object System.Drawing.Point(13,13) $grpSearch.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $grpSearch.TabStop = $False $grpSearch.Name = "grpSearch" # # btnSearch # $btnSearch.TabIndex = 2 $btnSearch.Name = "btnSearch" $btnSearch.Size = New-Object System.Drawing.Size(75,23) $btnSearch.UseVisualStyleBackColor = $True $btnSearch.Text = "Search" $btnSearch.Location = New-Object System.Drawing.Point(247,15) $btnSearch.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $btnSearch.add_Click($handler_btnSearch_Click) # # txtSearchUser # $txtSearchUser.Size = New-Object System.Drawing.Size(100,20) $txtSearchUser.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $txtSearchUser.Name = "txtSearchUser" $txtSearchUser.Location = New-Object System.Drawing.Point(128,18) $txtSearchUser.TabIndex = 1 # # lblSearchUsername # $lblSearchUsername.TabIndex = 0 $lblSearchUsername.RightToLeft = [System.Windows.Forms.RightToLeft]::No  $lblSearchUsername.TextAlign = [System.Drawing.ContentAlignment]::BottomRight  $lblSearchUsername.Size = New-Object System.Drawing.Size(100,23) $lblSearchUsername.Text = "Username:" $lblSearchUsername.Location = New-Object System.Drawing.Point(14,15) $lblSearchUsername.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $lblSearchUsername.Name = "lblSearchUsername" # # lblMessage # $lblMessage.TabIndex = 17 $lblMessage.Size = New-Object System.Drawing.Size(400,54) $lblMessage.Location = New-Object System.Drawing.Point(13,367) $lblMessage.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $lblMessage.Name = "lblMessage" # # btnBrowse # $btnBrowse.TabIndex = 15 $btnBrowse.Name = "btnBrowse" $btnBrowse.Size = New-Object System.Drawing.Size(75,23) $btnBrowse.UseVisualStyleBackColor = $True $btnBrowse.Text = "Browse..." $btnBrowse.Location = New-Object System.Drawing.Point(260,281) $btnBrowse.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $btnBrowse.add_Click($handler_btnBrowse_Click) # # txtThumbNailFile # $txtThumbNailFile.Size = New-Object System.Drawing.Size(209,20) $txtThumbNailFile.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $txtThumbNailFile.Name = "txtThumbNailFile" $txtThumbNailFile.Location = New-Object System.Drawing.Point(32,281) $txtThumbNailFile.TabIndex = 14 # # btnUpdateThumnail # $btnUpdateThumnail.TabIndex = 13 $btnUpdateThumnail.Name = "btnUpdateThumnail" $btnUpdateThumnail.Size = New-Object System.Drawing.Size(120,23) $btnUpdateThumnail.UseVisualStyleBackColor = $True $btnUpdateThumnail.Text = "Update Thumbnail" $btnUpdateThumnail.Location = New-Object System.Drawing.Point(260,179) $btnUpdateThumnail.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $btnUpdateThumnail.add_Click($handler_btnUpdateThumnail_Click) # # picBoxThumbnail # $picBoxThumbnail.TabIndex = 12 $picBoxThumbnail.Size = New-Object System.Drawing.Size(96,96) $picBoxThumbnail.Location = New-Object System.Drawing.Point(141,179) $picBoxThumbnail.TabStop = $False $picBoxThumbnail.Name = "picBoxThumbnail" $picBoxThumbnail.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  # # lblThumbnailPhoto # $lblThumbnailPhoto.TabIndex = 11 $lblThumbnailPhoto.TextAlign = [System.Drawing.ContentAlignment]::BottomRight  $lblThumbnailPhoto.Size = New-Object System.Drawing.Size(100,23) $lblThumbnailPhoto.Text = "thumbnailPhoto:" $lblThumbnailPhoto.Location = New-Object System.Drawing.Point(32,172) $lblThumbnailPhoto.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $lblThumbnailPhoto.Name = "lblThumbnailPhoto" # # btnCred # $btnCred.TabIndex = 10 $btnCred.Name = "btnCred" $btnCred.Size = New-Object System.Drawing.Size(108,23) $btnCred.UseVisualStyleBackColor = $True $btnCred.Text = "Change Credentials" $btnCred.Location = New-Object System.Drawing.Point(32,328) $btnCred.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $btnCred.add_Click($handler_btnCred_Click) # # btnUpdateEmployeeID # $btnUpdateEmployeeID.TabIndex = 9 $btnUpdateEmployeeID.Name = "btnUpdateEmployeeID" $btnUpdateEmployeeID.Size = New-Object System.Drawing.Size(120,23) $btnUpdateEmployeeID.UseVisualStyleBackColor = $True $btnUpdateEmployeeID.Text = "Update Employee ID" $btnUpdateEmployeeID.Location = New-Object System.Drawing.Point(260,149) $btnUpdateEmployeeID.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  # # txtEmployeeID # $txtEmployeeID.Size = New-Object System.Drawing.Size(100,20) $txtEmployeeID.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $txtEmployeeID.Name = "txtEmployeeID" $txtEmployeeID.Location = New-Object System.Drawing.Point(141,152) $txtEmployeeID.TabIndex = 8 # # lblEmployeeID # $lblEmployeeID.TabIndex = 7 $lblEmployeeID.TextAlign = [System.Drawing.ContentAlignment]::BottomRight  $lblEmployeeID.Size = New-Object System.Drawing.Size(108,23) $lblEmployeeID.Text = "Employee ID:" $lblEmployeeID.Location = New-Object System.Drawing.Point(27,149) $lblEmployeeID.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $lblEmployeeID.Name = "lblEmployeeID" # # txtSAMAccountName # $txtSAMAccountName.Size = New-Object System.Drawing.Size(100,20) $txtSAMAccountName.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $txtSAMAccountName.Name = "txtSAMAccountName" $txtSAMAccountName.Location = New-Object System.Drawing.Point(141,126) $txtSAMAccountName.Enabled = $False $txtSAMAccountName.TabIndex = 6 $txtSAMAccountName.add_TextChanged($handler_textBox3_TextChanged) # # lblSAMAccountName # $lblSAMAccountName.TabIndex = 5 $lblSAMAccountName.TextAlign = [System.Drawing.ContentAlignment]::BottomRight  $lblSAMAccountName.Size = New-Object System.Drawing.Size(108,23) $lblSAMAccountName.Text = "SAMAccountName:" $lblSAMAccountName.Location = New-Object System.Drawing.Point(27,123) $lblSAMAccountName.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $lblSAMAccountName.Name = "lblSAMAccountName" # # btnClose # $btnClose.TabIndex = 4 $btnClose.Name = "btnClose" $btnClose.Size = New-Object System.Drawing.Size(75,23) $btnClose.UseVisualStyleBackColor = $True $btnClose.Text = "Close" $btnClose.Location = New-Object System.Drawing.Point(251,328) $btnClose.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $btnClose.add_Click($handler_btnClose_Click) # # txtDomainName # $txtDomainName.Size = New-Object System.Drawing.Size(100,20) $txtDomainName.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $txtDomainName.Name = "txtDomainName" $txtDomainName.Location = New-Object System.Drawing.Point(141,100) $txtDomainName.Enabled = $False $txtDomainName.TabIndex = 3 # # lblDomainName # $lblDomainName.TabIndex = 2 $lblDomainName.TextAlign = [System.Drawing.ContentAlignment]::BottomRight  $lblDomainName.Size = New-Object System.Drawing.Size(108,23) $lblDomainName.Text = "Domain Name:" $lblDomainName.Location = New-Object System.Drawing.Point(27,97) $lblDomainName.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $lblDomainName.Name = "lblDomainName" # # lblUserName # $lblUserName.TabIndex = 1 $lblUserName.TextAlign = [System.Drawing.ContentAlignment]::BottomRight  $lblUserName.Size = New-Object System.Drawing.Size(108,23) $lblUserName.Text = "User Name:" $lblUserName.Location = New-Object System.Drawing.Point(27,71) $lblUserName.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $lblUserName.Name = "lblUserName" # # txtUserName # $txtUserName.Size = New-Object System.Drawing.Size(100,20) $txtUserName.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  $txtUserName.Name = "txtUserName" $txtUserName.Location = New-Object System.Drawing.Point(141,74) $txtUserName.Enabled = $False $txtUserName.TabIndex = 0 $txtUserName.add_TextChanged($handler_txtUserName_TextChanged) # # openfiledialog1 # $openfiledialog1.Filter = "JPEG Files (*.jpg)| *.jpg" $openfiledialog1.ShowHelp = $True #endregion Generated Form Code  #----------------------------------------------  #Save the initial state of the form $InitialFormWindowState = $frmUserInfoGUI.WindowState #Init the OnLoad event to correct the initial state of the form $frmUserInfoGUI.add_Load($Form_StateCorrection_Load) #Show the Form return $frmUserInfoGUI.ShowDialog()  } #End Function  #Call OnApplicationLoad to initialize if(OnApplicationLoad -eq $true) { #Create the form GenerateForm | Out-Null #Perform cleanup OnApplicationExit }

$LogPath="c:\scripts\logs\" $TranscriptLog = $LogPath + "_PhotoImport_" + $(get-date -uformat "%Y-%m-%d") + "_Transcript.log" Start-Transcript $TranscriptLog $StartTime = Get-Date  $Cred = Get-Credential $ImportFilename = "H:\scripts\PowerShell\AD Picture Import\EmployeePhotos.csv" $EmployeePhotoList = Import-Csv $ImportFilename $ImageDirPath = "\\server\share\Employee_Pics\96X96\" $message = "The bulk photo import script has completed `r`n`r`n"  foreach ($Employee in $EmployeePhotoList) {     $FullName= $Employee."First Name" + " " + $Employee."Last Name"     $User = Get-QADUser -Enabled -LdapFilter "(employeeNumber=$($employee."ID Number"))" -IncludedProperties thumbnailPhoto     If ($User -eq $null)      {         Write-Host -ForegroundColor red "Cannot find an enabled user with Employee Number $($Employee."ID Number") Name $FullName `r`n"         $message = $message + "Cannot find an enabled user with Employee Number " + $($Employee."ID Number") + ", Name" + $FullName + "`r`n`r`n"     }      ElseIF ($($User.DN) -eq $null)      {         Write-Host -ForegroundColor red "No Unique match with Employee Number $($Employee."ID Number") Name $FullName `r`n"         $message = $message + "No Unique match with Employee Number " + $($Employee."ID Number") + ", Name" + $FullName + "`r`n`r`n"     }     Else     {         #Get Filename Trim the extention from the original name add add the new base directory and postfix         $OrigImageName = $Employee."Image Number".substring(0, $($Employee."Image Number".length -4))         $ImagePath = $ImageDirPath + $OrigImageName + "_96x96.jpg"         $FileData=([byte[]]$(get-content -path $ImagePath -encoding byte -readcount 0))         if ($FileData -eq $null)         {             Write-Host -ForegroundColor red "Cannot find the Picture for Employee Number $($Employee."ID Number") Name $FullName `r`n"             $message = $message + "Cannot find the Picture for Employee Number " + $($Employee."ID Number") + ", Name" + $FullName + "`r`n`r`n"         }         Else         {             if ($User.thumbnailPhoto -eq $null)              {                 Write-Host -ForegroundColor Green "Importing Picture for Employee Number $($Employee."ID Number") Name $FullName `r`n"                 $message = $message + "Importing Picture for Employee Number " + $($Employee."ID Number") + ", Name" + $FullName + "`r`n`r`n"                 Set-QADUser -Identity "$($User.DN.ToString())" -ObjectAttributes @{thumbnailphoto=$FileData} -credential $Cred             }             Else             {                 Write-Debug "thumbnailPhoto already exists for Employee Number $($Employee."ID Number") Name $FullName `r`n"                 $message = $message + "thumbnailPhoto already exists for Employee Number " + $($Employee."ID Number") + ", Name" + $FullName + "`r`n`r`n"             }         }     } }  $StopTime = Get-Date $ElapsedTime =$StopTime - $StartTime Stop-Transcript  $smtpServer = "mail.blah.com" $To = "Kevin Curran <kcurran@blah.com>" $From = "AD Reporting <ADReporting@blah.com>" $message = $message + "please look at the attached log files for errors `r`n`r`n" $message = $message + "This script was run by " + $env:username + " on " + $env:COMPUTERNAME  $message = $message + " and ran for $([Math]::Round($ElapsedTime.TotalMinutes,0)) Minutes"  $Attachments = $TranscriptLog Send-MailMessage -From $From -To $To -SmtpServer $smtpServer ` -Subject "The bulk photo import script completed" -Body $message -Attachments $Attachments