How to send a chart as an email body using powershell - email

i have the following code. this is used to compare two dates for data and then saves it in a 3D chart.
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
$scriptpath = Split-Path -parent $MyInvocation.MyCommand.Definition
# chart object
$chart1 = New-object System.Windows.Forms.DataVisualization.Charting.Chart
$chart1.Width = 1300
$chart1.Height = 600
$chart1.BackColor = [System.Drawing.Color]::White
# title
[void]$chart1.Titles.Add("Order Rate")
$chart1.Titles[0].Font = "Arial,13pt"
$chart1.Titles[0].Alignment = "topLeft"
# chart area
$chartarea3D = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea3DStyle
# $chartarea.Name = "ChartArea1"
$chartarea3D.Enable3D = $true
$ChartArea = $chart1.ChartAreas.Add('ChartArea');
$ChartArea.Area3DStyle = $chartarea3D
$chartarea.AxisY.Title = "Orders"
$chartarea.AxisX.Title = "Hour"
$chartarea.AxisY.Interval = 200
$chartarea.AxisX.Interval = 1
# legend
$legend = New-Object system.Windows.Forms.DataVisualization.Charting.Legend
$legend.name = "Legend1"
$chart1.Legends.Add($legend)
# data source
#region Invoke sql
function Invoke-Sqlcmd2
<some code>
#endregion
$datasource = Invoke-Sqlcmd2 -ServerInstance yyyyyy -Database internetordering -Query "SELECT DATEPART(hh,createdon) AS hour, Count(*)Orders from dbo.OrderHeader (nolock )
where isimported = 1 and createdon between '01/27/2015 0:00:00' and '01/27/2015 23:59:59'
group by DATEPART(hh,createdon)"
$datasource2 = Invoke-Sqlcmd2 -ServerInstance zzzzzz -Database internetordering -Query "SELECT DATEPART(hh,createdon) AS hour, Count(*)Orders from InternetOrdering.dbo.OrderHeader (nolock )
where isimported = 1 and createdon between '01/28/2015 0:00:00' and '01/28/2015 23:59:59'
group by DATEPART(hh,createdon)"
# data series
[void]$chart1.Series.Add("OrdersLastMonthEOM")
#$chart1.Series["OrdersLastMonthEOM"].ChartType = "Column"
$chart1.Series["OrdersLastMonthEOM"].ChartType = "Line"
$chart1.Series["OrdersLastMonthEOM"].IsVisibleInLegend = $true
$chart1.Series["OrdersLastMonthEOM"].BorderWidth = 3
#$chart1.Series["OrdersLastMonthEOM"].chartarea = "ChartArea1"
$chart1.Series["OrdersLastMonthEOM"].Legend = "Legend1"
$chart1.Series["OrdersLastMonthEOM"].color = "#62B5CC"
$datasource | ForEach-Object {$chart1.Series["OrdersLastMonthEOM"].Points.addxy( $_.Hour , $_.Orders) }
# data series
[void]$chart1.Series.Add("OrdersThisMonthEOM")
#$chart1.Series["OrdersThisMonthEOM"].ChartType = "Column"
$chart1.Series["OrdersThisMonthEOM"].ChartType = "Line"
$chart1.Series["OrdersThisMonthEOM"].IsVisibleInLegend = $true
$chart1.Series["OrdersThisMonthEOM"].BorderWidth = 3
#$chart1.Series["OrdersThisMonthEOM"].chartarea = "ChartArea1"
$chart1.Series["OrdersThisMonthEOM"].Legend = "Legend1"
$chart1.Series["OrdersThisMonthEOM"].color = "#E3B64C"
$datasource2 | ForEach-Object {$chart1.Series["OrdersThisMonthEOM"].Points.addxy( $_.Hour , $_.Orders) }
# save chart
$chart1.SaveImage("$scriptpath\SplineArea2.png","png")
This creates a cool 3D Line graph on ISplineArea.png . I need a way to send this graph in a body of an email. Can anyone help with that.

From Here
In short, you have to send a message as HTML, attach pictures, set ContentID (cid) for every picture shown in your HTML and address them in img tag like <img src="cid:content-id-you-assigned" >
$EmailFrom = "NoReply#siteone.ok"
$EmailSubject = "Email including images in HTML"
$smtpServer = "mx1.siteone.ok"
$SendTo = "mailto#sitetwo.ok"
# Working with attachment and HTML code
$Image = "C:\scripts\MailScript\TestImage.png"
$att1 = new-object Net.Mail.Attachment($Image)
$att1.ContentType.MediaType = "image/png"
$att1.ContentId = "MyAttachment"
$mailmessage = New-Object system.net.mail.mailmessage
$mailmessage.Attachments.Add($att1)
$body = "<p style='font-family: Calibri, sans-serif'>
<img src='cid:MyAttachment' /><br />
This is a demonstration mail.
</p>"
$mailmessage.from = $emailfrom
$mailmessage.To.add($sendto)
$mailmessage.Subject = $emailsubject
$mailmessage.Body = $body
$mailmessage.IsBodyHTML = $true
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 25)
$SMTPClient.Send($mailmessage)
$att1.dispose()

Related

how to make power shell script from qrcode desktop application

I have created desktop application with generate qr code like below
I want make a script using batch script or powershell with the qrcode.exe based on value enter url and Qr Image Name using command line.the output should be QR Code Image too.
can try with this but first import the QRCodeGenerator before running the script
#Import-Module QRCodeGenerator
[string] $webname, [string] $url, [string] $output = ".\images\"
$webname = 'Google'
$url = 'https://www.google.com'
$outputfolder = $outputfolder + $webname +'.JPG'
New-PSOneQRCodeURI -URI $url -Width 15 -OutPath $output
and then the output result will be showing as JPG type.
Install-Module -Name QRCodeGenerator
Import-Module QRCodeGenerator
Add-Type -assembly System.Windows.Forms
$qr_base_form = New-Object System.Windows.Forms.Form
$qr_base_form.Height = 150
$qr_base_form.Width = 350
$qr_base_form.Text = "QR Code Generator"
$qr_base_form.AutoSize = $true
$qr_label_url = New-Object System.Windows.Forms.Label
$qr_label_url.Location = '10,10'
$qr_label_url.Size = '100,15'
$qr_label_url.Text = "URL:"
$qr_input_url = New-Object System.Windows.Forms.TextBox
$qr_input_url.Location = '10,30'
$qr_input_url.Size = '100,25'
$qr_label_name = New-Object System.Windows.Forms.Label
$qr_label_name.Location = '10,70'
$qr_label_name.Size = '100,15'
$qr_label_name.Text = "Name:"
$qr_input_name = New-Object System.Windows.Forms.TextBox
$qr_input_name.Location = '10,90'
$qr_input_name.Size = '100,25'
$qr_png_viewer = New-Object System.Windows.Forms.PictureBox
$qr_png_viewer.Image = $img
$qr_png_viewer.SizeMode = "Autosize"
$qr_png_viewer.Anchor = "Bottom, left"
$qr_png_viewer.Location = '150,10'
$qr_button_create = New-Object System.Windows.Forms.Button
$qr_button_create.Location = '150,150'
$qr_button_create.Size = '100,25'
$qr_button_create.Text = "Create Code"
$qr_button_create.Add_Click({
$path = "H:\LIVE\" + "$name"+ ".jpg"
$urllink = $qr_input_url.Text
$name = $qr_input_name.Text
New-PSOneQRCodeURI -URI "$urllink" -Width 15 -OutPath "$path"
$img = $path
})
$qr_base_form.Controls.Add($qr_label_url)
$qr_base_form.Controls.Add($qr_input_url)
$qr_base_form.Controls.Add($qr_label_name)
$qr_base_form.Controls.Add($qr_input_name)
$qr_base_form.Controls.Add($qr_png_viewer)
$qr_base_form.Controls.Add($qr_button_create)
$qr_base_form.ShowDialog()
This code should work for you. Just try changing the variables and try running it. GUI is also included.

Create AD user in a different domain

I created a series of scripts for creating domain users. Since every domain where we create users requires different parameters and conditions, I have one script for each domain. But in case of one domain I have a problem. For this domain the manual procedure is like this:
1) open dsa.msc
2) connect to the "xyz" domain (the user is being created from a server in "abc" domain)
3) Create the user (operation for 10 to 15 minutes, that's why I created the scripts)
Unfortunately, when I run my script, I get the error message, that "The server is unwilling to process the request" (That's the precise complete error message) during execution of New-ADUser cmdlet. I suppose the reason is the need to perform the step 2 in the procedure I described above. So I somehow need to simulate it in the script, but I have no idea how to do that.
This is how the command is defined:
$params = #{
'GivenName' = $First_name_val.Text
'Surname' = $Second_name_val.Text
'DisplayName' = $Display_name
'AccountPassword' = $password
'Path' = $Location_val.Text
'Name' = $User_name_val.Text
'CannotChangePassword' = $Cannot_chg_pass.Checked
'PasswordNeverExpires' = $Pass_not_expires.Checked
'ChangePasswordAtLogon' = $Must_chg_pass.Checked
'Enabled' = !($Account_disabled_val.Checked)
'Description' = $GECOS_val.Text
'Office' = "NA"
'OfficePhone' = "NA"
'Title' = $Job_Title_val.Text
'Department' = $Department_val.Text
'Company' = $Company_val.Text
'SamAccountName' = $User_name_val.Text
'UserPrincipalName' = $User_name_val.Text + "#woodplc.com"
'EmailAddress' = $Email_Address_val.Text
'PassThru' = $true
}
$New_user = New-ADUser #params
Definition of $User_name_val.Text is here:
#region Real name of the user
[void]$AD_user_creation.SuspendLayout()
$Display_name_lbl = New-Object system.Windows.Forms.Label
$Display_name_lbl.text = "User`'s real name"
$Display_name_lbl.AutoSize = $true
$Display_name_lbl.width = 25
$Display_name_lbl.height = 10
$Display_name_lbl.location = New-Object System.Drawing.Point(10,10)
$First_name_val = New-Object system.Windows.Forms.TextBox
$First_name_val.Text = "a."
$First_name_val.multiline = $false
$First_name_val.width = 120
$First_name_val.height = 20
$First_name_val.location = New-Object System.Drawing.Point(200,10)
$Second_name_val = New-Object system.Windows.Forms.TextBox
$Second_name_val.multiline = $false
$Second_name_val.width = 120
$Second_name_val.height = 20
$Second_name_val.location = New-Object System.Drawing.Point(330,10)
$Display_name_val = New-Object system.Windows.Forms.Label
$Display_name_val.Text = ""
$Display_name_val.width = 250
$Display_name_val.height = 20
$Display_name_val.location = New-Object System.Drawing.Point(200,40)
$showFullName = { $Display_name_val.Text = ($First_name_val.Text + "." + $Second_name_val.Text) }
[void]$Second_name_val.Add_Leave( { & $showFullName } )
[void]$First_name_val.Add_Leave( { & $showFullName } )
#endregion
#region User name of the user
$User_name_lbl = New-Object system.Windows.Forms.Label
$User_name_lbl.text = "User logon name"
$User_name_lbl.AutoSize = $true
$User_name_lbl.width = 25
$User_name_lbl.height = 10
$User_name_lbl.location = New-Object System.Drawing.Point(10,70)
$User_name_val = New-Object system.Windows.Forms.TextBox
$User_name_val.multiline = $false
$User_name_val.width = 250
$User_name_val.height = 20
$User_name_val.location = New-Object System.Drawing.Point(200,70)
$LogonName = {$User_name_val.Text = ($First_name_val.Text + "." + $Second_name_val.Text)}
[void]$Second_name_val.Add_Leave({& $LogonName})
[void]$First_name_val.Add_Leave({& $LogonName})
[void]$AD_user_creation.ResumeLayout()
#endregion
The error "The server is unwilling to process the request" means that some of your input values are invalid. For example, the OU you are providing could be invalid (maybe a space that shouldn't be there), or the SamAccountName might be too long or contain an invalid character, etc.
If you show the full command you are using I might be able to spot something.
If there was an issue connecting to the server or authenticating, then the error message would be different.

Cannot understand why this parameter is returning a null value

This PowerShell script runs a SQL query and populates an Excel spreadsheet, then emails that spreadsheet:
$FileName = "C:\Users\user\Documents\Report.xlsx";
$ConnectionString = "OurConnectionString"
$secpasswd = "emailpassword"
$cred = New-Object System.Management.Automation.PSCredential ("emailaddress", $secpasswd)
$SmtpCred = $cred
$ToAddress = 'to#contoso.com'
$FromAddress = 'from#contoso.com'
$SmtpServer = 'smtp.server.com'
$SmtpPort = '587'
$Subject = 'Report'
$Body = "Here is your report"
$SqlQuery = #"
SELECT TOP 10 * FROM dbo.table
"#;
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection;
$SqlConnection.ConnectionString = $ConnectionString;
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand;
$SqlCmd.CommandText = $SqlQuery;
$SqlCmd.Connection = $SqlConnection;
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter;
$SqlAdapter.SelectCommand = $SqlCmd;
$DataSet = New-Object System.Data.DataSet;
$SqlAdapter.Fill($DataSet);
$DataSetTable = $DataSet.Tables["Table"];
$xlsFile = #($DataSetTable | Export-Excel $FileName -AutoSize)
$SqlConnection.Close()
$Attachment = $xlsFile
$mailparam = #{
To = $ToAddress
From = $FromAddress
Subject = $Subject
Body = $Body
Attachments = $Attachment
SmtpServer = $SmtpServer
Port = $SmtpPort
Credential = $SmtpCred
}
Send-MailMessage #mailparam -UseSsl
The error I get when I run this is:
Send-MailMessage : Cannot validate argument on parameter 'Attachments'. The
argument is null, empty, or an element of the argument collection contains a
null value. Supply a collection that does not contain any null values and then
try the command again.
At C:\Users\Desktop\Untitled1.ps1:58 char:18
+ Send-MailMessage #mailparam -UseSsl
+ ~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage
I can't figure out how $Attachment is ending up as null or empty? I know I've written scripts similar to this in the past and they worked fine. Am I missing something in my script that someone else can see? Further, I don't technically need to save the Excel file to the file system first, I just need to email it as an attachment. So it's ok if the answer eliminates the saving to the file system part, if that's even do-able.
The -Attachments parameter expects a string or list of strings.
see Send-MailMessage
This should be the full path(s) to the file(s) you need to attach, thus requires you to store them first. Generally, if I don't need the files afterwards you can just delete them. Also note that it is required you pass the FullName.
As I cannot see the Output of the Export-Excel function I will assume it returns a File Object then this should work
$mailparam = #{
To = $ToAddress
From = $FromAddress
Subject = $Subject
Body = $Body
Attachments = $xlsFile.FullName
SmtpServer = $SmtpServer
Port = $SmtpPort
Credential = $SmtpCred
}
If you are not returned a File object you will need to get the item first and pass the `FullName'
$MyExcelFile = Get-Item -Path 'C:\MyExcelFile.xlsx'
$mailparam = #{
To = $ToAddress
From = $FromAddress
Subject = $Subject
Body = $Body
Attachments = $MyExcelFile.FullName
SmtpServer = $SmtpServer
Port = $SmtpPort
Credential = $SmtpCred
}

Getting more information selecting by a Combobox Powershell

Hello guys I'm currently coding an IHM in powershell to configure switches. I'm using a combobox to select a model. The combobx is generated using a dataview generated by a datasource, and the datasource is generated from a csv file by a foreach.
My problem is the following : I can only recover a single column.
Combobox:
$list1 = New-Object System.Windows.Forms.Combobox
$list1.Location = New-Object Drawing.Point 9,45
$list1.Size = New-Object System.Drawing.Size(250,30)
$list1.DropDownStyle = "DropDownList"
$list1.BindingContext = New-Object System.Windows.Forms.BindingContext
$list1.DataSource = $vu1
$list1.ValueMember = "Model"
$list1.DisplayMember = "Model"
$list1.SelectedValue = ""
$mainfrm.controls.add($list1)
Reading infos
Write-Host "$list1.SelectedValue"
Edit foreach and creation of the dataview
foreach:
$ImportData = import-csv "E:\PS\A faire\equipement.csv" -Delimiter ';' | Select Model,Type,Port,Firmware,Comware
$table1 = New-Object system.Data.DataTable
$colonne1 = New-Object system.Data.DataColumn Model,([string])
$table1.columns.add($colonne1)
$colonne2 = New-Object system.Data.DataColumn Port,([string])
$table1.columns.add($colonne2)
$colonne3 = New-Object system.Data.DataColumn Comware,([string])
$table1.columns.add($colonne3)
$colonne4 = New-Object system.Data.DataColumn Firmware,([string])
$table1.columns.add($colonne4)
foreach ($data in $ImportData)
{
$model = $data.Model
$type = $data.Type
$port = $data.Port
$firmware = $data.Firmware
$comware= $data.Comware
$ligne1 = $table1.NewRow()
$ligne1.Model = "$model "+"$type"
$ligne1.Port = "$port"
$ligne1.Comware = "$comware"
$ligne1.Firmware = "$firmware"
$table1.Rows.Add($ligne1)
}
Dataview
$vu1 = New-Object System.Data.DataView($table1)
Instead of using 4 colums in the datasource I put everything in one and then a split.
Code after :
$ligne1.Model = "$model "+"$type " + "$port " + "$comware " + "$firmware "
Then you can use a split() to have a usable value.

Powershell Error creating entry through WSDL SOAP connection

So I am getting a conversion error when submitting something via WSDL SOAP in PowerShell.
I am trying to create entries in a system called Kablink however although the entry has all the values etc. in the variable $soapData when I attempt the actual creation I get an error about being unable convert argument entry from one value to another even though both specified values are the same.
Cannot convert argument "entry", with value: "folder_addEntry.FolderEntry", for "folder_addEntry" to type "folder_addEntry.FolderEntry": "Cannot convert the "folder_addEntry.FolderEntry" value of type
"folder_addEntry.FolderEntry" to type "folder_addEntry.FolderEntry"."
Any ideas would be hugely appreciated as this is now driving me insane.
Below is the script I am using
$kablinkSoapUrl = "http://servername/ssr/secure/ws/TeamingServiceV1?wsdl"
$kablinkConnector = New-WebServiceProxy -Uri $kablinkSoapUrl -Credential $Credential -namespace "folder_addEntry"
#Set Binder ID to Shift Rota entries folder
$binderID = 155
#write-host $soapData
#Import Objects and Populate Default Values
$soapDescription = New-Object ("folder_addEntry.Description")
$soapDescription.text = "Some Description"
$soapDescription.format = 0
$soapAttachment = New-Object("folder_addEntry.attachmentsField")
$soapAttachment.name = ""
$soapAttachment.type = ""
$soapAttachment.attachments = #()
$soapCreate = New-Object ("folder_addEntry.Timestamp")
$soapCreate.date = get-date
$soapCreate.principal = ""
$soapCreate.principalId = 2
$soapModify = New-Object ("folder_addEntry.Timestamp")
$soapModify.date = get-date
$soapModify.principal = ""
$soapModify.principalId = 2
$soapRating = New-Object ("folder_addEntry.AverageRating")
$soapRating.averageRating = ""
$soapRating.ratingCount = ""
$soapCustBool = New-Object ("folder_addEntry.CustomBooleanField")
$soapCustBool = #()
$soapCustDate = New-Object ("folder_addEntry.CustomDateField")
$soapCustDate = #()
$soapCustEven = New-Object ("folder_addEntry.CustomEventField")
$soapCustEven = #()
$soapCustLong = New-Object ("folder_addEntry.CustomLongArrayField")
$soapCustLong = #()
$soapCustStriArr = New-Object ("folder_addEntry.CustomStringArrayField")
$soapCustStriArr = #()
$soapCustStr = New-Object ("folder_addEntry.CustomStringField")
$soapCustStr = #()
#Construct Entry
$soapData = New-Object -TypeName folder_addEntry.FolderEntry
$soapData.attachmentsField = $soapAttachment
$soapData.averageRating = $soapRating
$soapData.creation = $soapCreate
$soapData.customBooleanFields = $soapCustBool
$soapData.customDateFields = $soapCustDate
$soapData.customEventFields = $soapCustEven
$soapData.customLongArrayFields = $soapCustLong
$soapData.customStringArrayFields = $soapCustStriArr
$soapData.customStringFields = $soapCustStr
$soapData.definitionId = "8a8ab38c62d40d5c0162fc8330eb01ad"
$soapData.description = $soapDescription
$soapData.entityType = "fileEntry"
$soapData.eventAsIcalString = 0
$soapData.family = "file"
$soapData.id = ""
$soapData.modification = $soapModify
$soapData.parentBinderId = 155
$soapData.permaLink = ""
$soapData.title = "PowerShell Entry"
$soapData.docLevel = 1
$soapData.docNumber = ""
$soapData.href = ""
$soapData.preDeleted = 0
$soapData.preDeletedBy = ""
$soapData.preDeletedWhen = ""
$soapData.reservedBy = ""
$soapData.workflows = #()
# Print Soap Data
$soapData
# Submit Entry
$kablinkConnector.folder_addEntry("",$soapData,"")
Thanks in advance.
Added -class "folder_getEntry" when creating the $kablinkConnector variable making the line
$kablinkConnector = New-WebServiceProxy -Uri $kablinkSoapUrl -Credential $Credential -namespace "folder_addEntry" -class "folder_getEntry"
And now it works