Changing report name in SSRS email subscription - reporting-services

We are using SSRS 2012 at my company and we use a plug-in to append a datestamp to about 5% of the emailed report names (along with ZIPping a few of them), as it looks like you can't set up an email subscription and then script the attached report name changes, can only do that when your subscription writes to a file share.
This plug-in is no longer supported and fails quite a bit for no obvious reason. The workaround of writing these reports to a file share then scripting the email process from there is not a practical solution for us.
We will be upgrading to SSRS 2019 this year, can anyone tell me if modifying emailed report names is now an option, I am finding no definitive answer online. Or is there a supported reliable plug-in anyone can recommend, that adds datestamps to email subscription attached report names and can compress those reports?

If you have custom requirements for emailing subscriptions, you can setup a PowerShell script to run on a server under a scheduled task.
Here is an example were I export a Tableau workbook and SSRS report to pdf, zip them and send it as an email.
<#
Description: Powershell Report Subscription
Purpose: To export pdf files from SQL Server Reporting Services and Tableau and then email them as attachments.
References: https://onlinehelp.tableau.com/current/server/en-us/tabcmd_cmd.htm#id7cb8d032-a4ff-43da-9990-15bdfe64bcd0
As Is: Deployed to C:\Temp and running on a schedule with Windows Task Scheduler
#>
Try
{
#set email variables
$smtpServer = 'YourServer.com';
$emailSubject = 'Weekly Report';
$emailFrom = 'Business.Intelligence#yourcompany.com';
$emailError = 'Business.Intelligence#yourcompany.com';
$emailTo = #('John Smith <john.smith#yourcompany.com>', 'Dave Scott <dave.scott#yourcompany.com>');
$emailCc = 'Business.Intelligence#yourcompany.com';
$exportPath = 'C:\Temp\';
$zipFile = $exportPath + 'reports';
#set Tableau variables
$tableauServer = 'TABLEAU_SERVER';
$tableauUsername = 'your_service_account'; #user must have read/write permissions to $exportPath
$tableauPassword = '###################';
$tableauTabCmdPath = 'C:\Program Files\Tableau\Tableau Server\2019.3\extras\Command Line Utility\tabcmd.exe';
$tableauWorkbook = 'YourFolder/YourWorkbook';
$tableauFile = $exportPath + $tableauWorkbook.Substring($tableauWorkbook.IndexOf('/')+1) + '.pdf';
#set SSRS variables
$ssrsPath = 'http://SSRS_SERVER/ReportServer/Pages/ReportViewer.aspx?%2fFinance/Weekly%20Report';
$ssrsFileName = $ssrsPath.split('/')[-1] -replace '%20', ' ';
$ssrsFile = $exportPath + $ssrsFileName + '.pdf';
#remove files if they already exist so we don't send out old reports
if (Test-Path $tableauFile)
{
Remove-Item $tableauFile
}
if (Test-Path $ssrsFile)
{
Remove-Item $ssrsFile
}
#create pdf of SQL Server Reporting Services (SSRS) report
$ssrsFilePdf = $ssrsPath + '&rs:Format=PDF'
(Invoke-WebRequest -Uri $ssrsFilePdf -OutFile $ssrsFile -UseDefaultCredentials -TimeoutSec 240);
#create pdf of Tableau workbook
$tableauServer = $tableauServer;
$tableauWorkbookRefresh = $tableauWorkbook + '?:refresh=yes';
$TabCmd = $tableauTabCmdPath;
& $TabCmd login -s $tableauServer -u $tableauUsername -p $tableauPassword;
& $TabCmd export $tableauWorkbookRefresh -pdf -f $tableauFile;
& $TabCmd logout;
#compress files
Compress-Archive -Path $exportPath -DestinationPath $zipFile
$zipFile = $zipFile + '.zip'
#email attachments to users
Set pathname ="C:\Windows\System32\WindowsPowerShell>";
$emailBody = #"
Hi,
Attached are the weekly reports.
This is a link to the Tableau Workbook Weekly Report
http://$tableauServer/#/views/$tableauWorkbook
This is a link to the Report Manager Weekly Report
$ssrsPath
"#
Send-MailMessage -smtpServer $smtpServer -From $emailFrom -To $emailTo -Cc $emailCc -Subject $emailSubject -Attachments $zipFile -Body $emailBody;
}
Catch
{
$errorType = $_.Exception.GetType().FullName;
$errorMessage = $_.Exception.Message;
$scriptFileName = $MyInvocation.MyCommand.Name;
$scriptFileCode = $MyInvocation.MyCommand.Definition;
Write-Host "Exception:" -ForegroundColor Red;
Write-Host "Exception Type: $($_.Exception.GetType().FullName)" -ForegroundColor Red;
Write-Host "Exception Message: $($_.Exception.Message)" -ForegroundColor Red;
Send-MailMessage -smtpServer $smtpServer -From $emailFrom -To $emailError -Subject "$emailSubject FAILED!" -Body " Host Name: $env:computername `n Error Type: $errorType `n Error Message: $errorMessage. `n`n Script File: $scriptFileName `n Script Code: `n $scriptFileCode";
Break;
}

Related

What is the ItemType for SSRS Catalog Type 14?

SQL Server 2019. I manually uploaded a xlsx file to the server and it was placed in an "Excel Workbooks" group. When I look in the reportserver catalog table I see the Type value is 14. I'm trying to write a powershell script to upload a bunch of xlsx files instead of having to do it manually, one by one. I need to know the ItemType. I can use "Resource" but it doesn't upload it to the "Excel Workbooks" group, it uploads it to the "Resources" group. I did list everything in my report server and see the TypeName for the xlsx I manually uploaded is "ExcelWorkbook", but is not a valid ItemType. Any suggestions? Below is the powershell I'm using (I'm still new to powershell). Thanks!
$WebServiceUrl = "http://xxxx"
$ReportFolder = "PDF_Reports2"
$SourceDirectory = $PSScriptRoot
$Overwrite = $true
$SSRSProxy = New-WebServiceProxy -Uri $WebServiceUrl'/ReportServer/ReportService2010.asmx?WSDL' -UseDefaultCredential
# LIST ITEMS IN SERVER
#$SSRSProxy.ListChildren("/",$true)
$type = $SSRSProxy.GetType().Namespace
$datatype = ($type + '.Property')
$Property =New-Object ($datatype);
$Property.Name = "MimeType"
$Property.Value = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
$SourceDirectory = "c:\tmp\SSRS\"
$ItemType = "Resource" # Resource works, but it gets put in the Resources group, I want it in the Excel Workbooks group.
$ReportFolder = "/PDF_Reports2"
ForEach ($rdlfile in Get-ChildItem $SourceDirectory -Filter "*.xlsx" | Where-Object { $_.Attributes -ne "Directory" } )
{
$byteArray = [System.IO.File]::ReadAllBytes($rdlfile.FullName)
write-host $rdlfile.FullName
$Warnings = #();
$SSRSProxy.CreateCatalogItem($ItemType, $rdlfile, $ReportFolder, $Overwrite, $byteArray, $Property, [ref]$Warnings)
$warnings.Length
}

How can you pass the HashTable as a parameter to the function and export the data into the csv?

I have build the PowerShell module function which captures the data such as:
Start Date
Start Time
Server Name
User (who executes the script
Technology
Script Name
Script Path
Execution Time (# of seconds took the script from start to end)
Error Message (if there is any error message in the script)
The above points provides data for each of the script, I have enabled the module and calling out the function in each of my script. However, there are some scripts which provides build data and some scripts which don't. For example, there is one script which enables MS Project and MS Visio license to the end users and it gives me the data on # of Project license assigned and # of Visio license assigned.
I am trying to find the way on how to capture the build data from some of my scripts. I want to capture the data with headers and merge them with my HashTable which is in my module script. Altogether, I want to export the data to the csv file.
I am trying to understand what I am missing? I used param method but couldn't output any data.
Here is my PowerShell module code
function Get-Info(){
$date = (Get-Date -f "MM_dd_yyyy_hh_mm")
#TimeStamp
$reportDate = (Get-Date -f "MM/dd/yyyy")
$reportTime = (Get-Date -f "hh:mm:ss tt")
#Server
$serverName = $env:COMPUTERNAME
#user
$user = $env:UserName
#script name
$scriptName = split-path $MyInvocation.PSCommandPath -Leaf
#script path
$scriptPath = split-path $MyInvocation.PSCommandPath
#service account
$serviceAccount = $tenantAdmin
#measure execution time (start to finish)
[timespan]$executionTime = Measure-Command {0..10000 | ForEach-Object {$i++} }
$runTime = $executionTime.Milliseconds
#Technology Type
$technology = Split-Path (Split-Path $scriptPath -Parent) -Leaf
#error handling
If($errorMessage -eq $null){
$errorMessage = "None"
}
if ($errorMessage -ne $null){
$errorMessage = $ErrorMessage
}
$fileName = $scriptName.Trim(".ps1")
$Hashtable = #()
$Hashtable += New-Object psobject -Property #{
"Script Name" = $scriptName;
"Execution Date" = $reportDate;
"Execution Time" = $reportTime;
"Service Account" = $serviceAccount;
"User" = $user;
"Server Name" = $serverName;
"Script Path" = $scriptPath;
"RunTimeMS" = $runTime;
"Error Message" = $errorMessage;
"Technology" = $technology;
}
if($myHashTable -eq $null){
$Hashtable | Export-Csv "D:\MyFileName\$fileName$date.csv" -NoTypeInformation
}
if($myHashTable -ne $null){
$finalTable = $Hashtable + $myHashTable
$finalTable | Export-Csv "D:\MyFileName\$fileName$date.csv" -NoTypeInformation
}

importing HTML and outputting with variables

I'm looking for a method to import a template HTML file in PowerShell and being able to populate it with variables, which in turn sends an e-mail in HTML format containing user data.
I already know how to send the HTML e-mail. And, currently have HTML in a 'here' string embedded in the code. I want to take it a step further, by being able to grab an HTML template based on country code. So, if the user is in the US, it'll get a English HTML data filled e-mail, if they're dutch, they'll get it in Dutch, etc.
function SendMessage {
Param(
[Parameter(Position=0,Mandatory=$true)]
[string]$Identity,
[Parameter(Position=1,Mandatory=$true)]
[string]$Body
)
$Subject = "Important information - Do not delete this email. Welcome to Voicemail"
$SmtpClient = New-object system.net.mail.smtpClient
$MailMessage = New-Object system.net.mail.mailmessage
$CredentialFile = ".\UMcloud-creds.txt"
$password = Get-Content $CredentialFile| ConvertTo-SecureString -Force
$UMCloudAdmin = ""
$SmtpClient.Credentials = New-Object System.Net.NetworkCredential($UMCloudAdmin, $Password)
$smtpclient.Host = "smtp-in.net"
$MailMessage.From = "Voicemail <P#domain.net>"
$MailMessage.To.clear()
$MailMessage.To.Add($Identity)
$MailMessage.Subject = $Subject
$Mailmessage.Body = $body
$MailMessage.IsBodyHtml = 1
$Logofilepath = ((Resolve-Path .\).Path) + "\logo.jpg"
$attachment = New-Object System.Net.Mail.Attachment -ArgumentList $LogoFilePath
$attachment.ContentDisposition.Inline = $True
$attachment.ContentDisposition.DispositionType = "Inline"
$attachment.ContentType.MediaType = "image/jpg"
$attachment.ContentId = "logo.jpg"
$MailMessage.Attachments.Add($attachment)
do {
$Continue = $false
try {
$smtpclient.Send($MailMessage)
Write-LogFile $OutputLogFile ("[SUCCESS] {0} {1}" -f $identity, $UMExtension)
Write-LogFile $customemaillog ("[SUCCESS] {0} {1}" -f $identity, $UMExtension) | out-null
$Continue = $true
} catch {
sleep -s 10
Write-LogFile $OutputLogFile "[ERROR] $Identity $_.Exception.Message"
Write-LogFile $CustomEmailLog "[ERROR] $Identity $UMExtension"
Write-Error $_.Exception.Message
}
} until($Continue -eq $true)
} # End send message
$WelcomeText = Get-Content -Path ".\$CountryID.txt"
$Body = #"
<html>
...
</html>
"#
The here string is part of the script, I'd like to be able to import it from TXT file as not to clutter the script.
Instead of using a text file, create a powershell file (ps1) for each html language format you want. Within those files, you can set a single variable as the html text (file EN_US.ps1):
$bodyENUS = #"Dear <b><font color=red>user</b></font> <br>
This is a test <b>HTML</b> email for your language preference<br>
Sincerely,<br> PdeRover<br>"
You can then pass the variable into the main ps file using two ways: Dot Sourcing or using a Global Variable.
Dot Sourcing: calling the variable by providing the file name.
In the main file:
..\EN_US.ps1
..\PT_PT.ps1
$smtp = "Exchange-Server"
$to = $Identity
$from = "Voicemail <P#domain.net>"
$subject = "This is a Test of HTML Email"
if (user is English speaking){
$bodyByLang = $bodyENUS}
elseif (user is Portuguese speaking) {
$bodyByLang = $bodyPTPT}
send-MailMessage -SmtpServer $smtp -To $to -From $from -Subject $subject -Body $bodyByLang -BodyAsHtml -Priority high
Global Variable: prefixing a variable with $Global:and calling the file during runtime. $Global: bodyENUS Then calling it using $bodyENUS
I asked my own SO question about the difference/best practice of using them. May be worth a read.
This should be enough to point you in the right direction.

How to correctly pass variables & source version to API 2.0 VNext Build in TFS 2015

I'm having difficulty finding how the correct way to pass defined variables and build definition arguments to the new API 2.0 build engine with TFS 2015. I'm using TFS 2015 Update 3 on-premise .
I've triggered a POST with powershell that looks like this:
$Build_Definition_ID = 1234
$TFSInstanceURL = 'http://tfsservername:port/tfs'
$ProjectCollection = 'CollectionName'
$TeamProject = 'ProjectName'
$Changeset = "12345"
$UserName = "$env:USERDOMAIN\$env:USERNAME"
$UserNamePartial = $env:USERNAME
$body = #"
{
"definition": {
"id": "$Build_Definition_ID"
}
}
"#
$baseUri = $TFSInstanceURL+"/"+$ProjectCollection+"/"+$TeamProject+"/_apis/build"
$postUri = $baseUri+"/builds?api-version=2.0"
##Create a new PSCredential based on username/password
$User = 'foo\bar'
$Password = 'examplepass'
$securePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($User, $securePassword)
### Queue a build ###
##Call the REST API for TFS that does a POST request to queue a build with the body of the request to be the build definition
$buildResponse = Invoke-RestMethod -Method POST -Credential $credential -ContentType application/json -Uri $postUri -Body $body
#Write-Host (ConvertTo-Json $buildResponse)
#ConvertTo-Json $buildResponse | out-file -FilePath $Changeset-ResponseJson.json -Force
The powershell script is successfully launching the definition. However, I'm still not successfully:
- Passing in the specific source version I want to run against (example C12345)
- Passing in the custom variable values
Additionally:
If you know of the proper way to pass in the arguments such as the folder to map from source (to allow dynamically choosing different branches) then this would help.
Current resources I've evaluated:
Visual Studio Docs > Api > Build > Builds
Postman - GET - Definition Details - Reviewed response for possible correct structure to submit
The body part for the REST API should look like:
{
"definition": {
"id": 28
},
"sourceBranch": "$/xxxx/xxxx",
"SourceVersion": "Cxxxx",
}
Then you can specify the sourceBranch and SourceVersion.
===================================================================
An example:
$Build_Definition_ID = '28'
$TFSInstanceURL = 'http://tfsservername:port/tfs'
$ProjectCollection = 'DefaultCollection'
$TeamProject = 'TestCase'
$Changeset = "C139"
$sourceBranch = "$/TestCase/TestCaseProject-branch"
$body = #"
{
"definition": {
"id": "$Build_Definition_ID"
},
"sourceBranch": "$sourceBranch",
"SourceVersion": "$Changeset",
}
"#

Resolve DNS, export to Excel and HTML, then send mail

I was almost done with my script and did some late night editing and written over my old version so I cannot go back.
The script was running fine, still needed some tweaks but now it ha come to a complete halt.
The idea is to GC a list of IP's. Resolve the IP's and place them in an excel sheet. Then save the sheet to htm and xlsx. And finally mailing those to me.
Now it gets stuck on sorting the sheet, saving AND mailing...
Can someone give me some insight on what I did wrong here?
it gets stuck on sorting the sheet, saving AND mailing.
It no longer sorts B3:B$Count:
Exception calling "Sort" with "1" argument(s): "The sort reference is not valid. Make sure that it's within the data you want to sort, and the first Sort By box isn't the same or blank."
At C:\Folder\Scripts\Get-IP.ps1:137 char:5
+ [void] $objRange.Sort($objRange2)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
It no longer saves the xlsx file, but does save the HTM file. It is clearly not overwriting something. I even restarted to make sure.
Exception calling "SaveAs" with "1" argument(s): "Microsoft Excel cannot access the file 'C://Folder/BlockedIP/HTML/2014-07-08/0BCEF810'. workbook."
At C:\Folder\Scripts\Get-IP.ps1:160 char:5
+ $b.SaveAs("$FileXML")
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
And finally, it will no longer send me e-mails:
New-Object : Exception calling ".ctor" with "2" argument(s): "The specified string is not in the form required for an e-mail address."
At C:\Folder\Scripts\Get-IP.ps1:217 char:13
+ $SMTP = New-Object System.Net.Mail.MailMessage($SMTP, 587)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
The script:
#Get current date
$Date = get-date -format yyyy-MM-dd
#Define all files/Paths.
$Path = "C:/Folder/BlockedIP"
md "$Path/HTML/$Date" -Force
$path2 = "$Path/HTML/$Date"
$PathWeb = "/HTML/$Date"
#Define File's used or created in this script.
$File = "$Path/IP-$Date.txt"
$FileHtml = "$Path2/IP-$Date.htm"
$FileXML = "$Path2/IP-$Date.xlsx"
$FileHTMLWeb = "$PathWeb/IP-$date.htm"
#Get content from given IP list.
$colComputers = #(get-content $File | Sort -unique)
$count = $colComputers.Count
write-output "$Count IP's detected."
#Define error actions.
#$erroractionpreference = "SilentlyContinue"
#Open Excel.
$a = New-Object -comobject Excel.Application
#Since we want this script to look like it's being used without excel I set it's visibility to false.
$a.visible = $True
#Disable excel confirmations.
$a.DisplayAlerts = $False
#Create sheets in Excel.
$b = $a.Workbooks.Add()
$c = $b.Worksheets.Item(1)
#Create a Title for the first worksheet and adjust the font
$row = 1
$Column = 1
target="_parent">Creator'
$c.Cells.Item($row,$column)= "Blocked IP's $Date"
$c.Cells.Item($row,$column).Font.Size = 18
$c.Cells.Item($row,$column).Font.Bold=$True
$c.Cells.Item($row,$column).Font.Name = "Cambria"
$c.Cells.Item($row,$column).Font.ThemeFont = 1
$c.Cells.Item($row,$column).Font.ThemeColor = 4
$c.Cells.Item($row,$column).Font.ColorIndex = 55
$c.Cells.Item($row,$column).Font.Color = 8210719
$range = $c.Range("a1","e1")
$range.Merge() | Out-Null
$range.VerticalAlignment = -4160
#Define subjects.
$c.Name = "Blocked IP's ($Date)"
$c.Cells.Item(2,1) = "Given IP"
$c.Cells.Item(2,2) = "Resolved DNS"
$c.Cells.Item(2,3) = "Returned IP"
$c.Cells.Item(2,5) = "Company name"
#Define cell formatting from subjects.
$c.Range("A2:E2").Interior.ColorIndex = 6
$c.Range("A2:E2").font.size = 13
$c.Range("A2:E2").Font.ColorIndex = 1
$c.Range("A2:E2").Font.Bold = $True
#Define the usedrange for autofitting.
$d = $c.UsedRange
#Make everything fit in it's cell
$D.EntireColumn.AutoFit() | Out-Null
#Define html code for Excel save to .htm.
$xlExcelHTML = 44
#Define rows to alter in excel.
$iRow = 3
$intRow = 3
#Time to run the script.
foreach ($strComputer in $colComputers)
{
#Place IP's from text in the excel sheet
$c.Cells.Item($intRow, 1) = $strComputer.ToUpper()
$d.EntireColumn.AutoFit() | Out-Null
#Create a status bar for the script
$i = 1
Write-Progress -Activity `
"Creating a usable 'Blocked IP' list ($i/$count)" `
-PercentComplete ($i/$colComputers.Count*100) `
-Status "Please stand by"
try {
$dnsresult = [System.Net.DNS]::GetHostEntry($strComputer)
}
catch {
$dnsresult = "$null"
}
#Clear screen on every checked IP to remove the 'True' statement.
#cls
#Do something with $dnsresults.
#Display information about host
#Give hostname Entry in Cell2
$c.Cells.Item($intRow,2) = $dnsresult.HostName
#IP listed in Cell 3
$c.Cells.Item($intRow,3) = $dnsresult.AddressList[0].IpAddressToString
#Make everything fit in it's cell.
$d.EntireColumn.AutoFit() | Out-Null
#Define row for the IP list.
$intRow = $intRow + 1
#Set background color for the IP list.
$d.Range("A$($iRow):E$($intRow)").interior.colorindex = 15
#Sort all IP's on resolved name.
$objWorksheet = $b.Worksheets.Item(1)
$objRange = $objWorksheet.UsedRange
$objRange2 = $objworksheet.Range("B3:B($Count)")
[void] $objRange.Sort($objRange2)
#Define borders here.
<# Insert script :D #>
#Define Filters here. (Picking out blank DNS and giving those a name)
<# Insert script :D #>
#Define Filters here. (Picking out specific DNS name and give them color code)
<# Insert script :D #>
#Make everything fit in it's cell.
$d.EntireColumn.AutoFit() | Out-Null
#Clear screen on every checked IP to remove the 'True' statement.
#cls
}
#Save the file as .xlsx on every placed IP to ensure the file is not lost due to any reason.
$b.SaveAs("$FileXML")
#Save final result as a .htm file
$b.SaveAs("$FileHTML",$xlExcelHTML)
#Close and quit Excel.
$b.Close()
get-process *Excel* | Stop-Process -force
#Move .txt file to the correct HTML folder.
move-item $file $path2 -Force
#Clear screen, again. (Let's keep things tidy.)
#cls
#Variables for public IP
# I am defining website url in a variable
$url = "http://checkip.dyndns.com"
# Creating a new .Net Object names a System.Net.Webclient
$webclient = New-Object System.Net.WebClient
# In this new webdownlader object we are telling $webclient to download the
# url $url
$IpPublic = $webclient.DownloadString($url)
# Just a simple text manuplation to get the ipadress form downloaded URL
# If you want to know what it contain try to see the variable $IpPublic
$IpPublic2 = $IpPublic.ToString()
$ipPublic3 = $IpPublic2.Split(" ")
$ipPublic4 = $ipPublic3[5]
$ipPublic5 = $ipPublic4.replace("</body>","")
$FinalIPAddress = $ipPublic5.replace("</html>","")
#Variables e-mail.
$From = "Blocked IP <###g##.com>"
$To = "IT Dept <#####.nl>"
$CC = "Someone <##r###.nl"
$SMTP = "smtp.gmail.com"
$Subject = "Blocked IPs for $date ($Count Total)"
#The href should point to the htm file in your iis/apache folder.
$WebLink = $FinalIPAddress+$FileHtmlWeb
$here = "<a href='http://$Weblink'><b>Here</b></a>"
#Define the body of your e-mail, in this case it displays a message and shows the server it is send from with it's local IP.
#A link to the .htm file, how many IP's were blocked and the date of the message.
$Body = "This is an automated message generated by server: $env:COMPUTERNAME, $IP</br></br>
Please see the attachment or click $here to get the $Count blocked IP's of $date. </br> </br></br>"
#Variables e-mail user.
$username = "#####.com"
$password = "##"
$secstr = New-Object -TypeName System.Security.SecureString
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$Cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr
$ip = (Get-WmiObject -class win32_NetworkAdapterConfiguration -Filter 'ipenabled = "true"').ipaddress[0]
#Clear screen, again. (Let's keep things tidy.)
#cls
#Send output as e-mail.
$SMTP = New-Object System.Net.Mail.MailMessage($SMTP, 587)
$SMTP.EnableSsl = $true
$SMTP.Credentials = New-Object System.Net.NetworkCredential("$username", "$password");
$SMTP.isbodyhtml= $true
$SMTP.Send($From, $To, $Subject, $FileXML, $Body)
send-mailmessage -BodyAsHtml -from $From -to $To -cc $CC -subject $Subject -Attachments $FileXML -body $Body -priority High -smtpServer $SMTP -credential ($cred) -usessl
#Create a function to relase Com object at end of script.
function Release-Ref ($ref) {
([System.Runtime.InteropServices.Marshal]::ReleaseComObject(
[System.__ComObject]$ref) -gt 0)
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}
#Release COM Object
[System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$a) | Out-Null
#Clear screen for the final time. (Let's keep things tidy.)
#cls
#Exit powershell
exit
Any help will be greatly appreciated!
Exception calling "Sort" with "1" argument(s): "The sort reference is not valid. Make sure that it's within the data you want to sort, and the first Sort By box isn't the same or blank."
Double-check that $objRange and $objRange2 reference the correct ranges:
$objRange.Address()
$objRange2.Address()
Not much else I can tell you here without seeing your actual data.
Exception calling "SaveAs" with "1" argument(s): "Microsoft Excel cannot access the file 'C://Folder/BlockedIP/HTML/2014-07-08/0BCEF810'. workbook."
If the path really were C://Folder/... you'd be getting a different exception. Please do not fabricate error messages.
New-Object : Exception calling ".ctor" with "2" argument(s): "The specified string is not in the form required for an e-mail address."
You're confusing MailMessage and SmtpClient class. Not to mention that you don't even need either of them, since you're using Send-MailMessage anyway. Just remove the following 5 lines:
$SMTP = New-Object System.Net.Mail.MailMessage($SMTP, 587)
$SMTP.EnableSsl = $true
$SMTP.Credentials = New-Object System.Net.NetworkCredential("$username", "$password");
$SMTP.isbodyhtml= $true
$SMTP.Send($From, $To, $Subject, $FileXML, $Body)
Solved the sorting problem by altering the code to:
$objRange = $c.Range("A$($iRow):E$($intRow)")
$objRange2 = $c.Range("B$($iRow):B$($intRow)")
[void] $objRange.Sort($objRange2)
Turns out it got stuck on the header in the xml file
Replaced mailing with:
$From = "Blocked IP <#####.##>"
$To = "IT Dept <#####.##>"
$CC = "Someone <#####.##"
$Subject = "Blocked IPs for $date ($Count Total)"
#The href should point to the htm file in your iis/apache folder.
$WebLink = $FinalIPAddress+$FileHtmlWeb
$here = "<a href='http://$Weblink'><b>Here</b></a>"
#Define the body of your e-mail, in this case it displays a message and shows the server it is send from with it's local IP.
#A link to the .htm file, how many IP's were blocked and the date of the message.
$body = "Dear <font color=black>$to</font>,<br><br>"
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
$Username = "###gmail.com"
$Password = "##"
$message = New-Object System.Net.Mail.MailMessage
$message.IsBodyHTML = $true
$message.ReplyTo = $From
$message.Sender = $From
$message.subject = $subject
$message.body = $body
$message.to.add($to)
$message.from = $username
$message.attachments.add($MailXML)
$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
$smtp.EnableSSL = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
$smtp.send($message)
The saving of the file turned out to be a misguided path.
Since the excel sheet was created from folder1 it wouldnt save instandly to folder 2 since its temp save file would remain in folder1.