i am trying to get running services on the email, result is coming on powershell but on email it is showing system.object, can some one please help
rohit mahajan,
Welcome to the forum.
This usually indicates that there is an array of objects instead of a single object. But without seeing your actual code thereās little to no chance to actually help you with your issue. So if you need any further assistance you should show the code youāre using.
Shall i post code here or can you give me your personal email id
Post it here and format it as code please.
When you post code, sample data, console output or error messages please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.
Thanks in advance
How to format code in PowerShell.org 1 <---- Click
( !! Sometimes the preformatted text button hides behind the settings gear symbol. )
$To = "sss@hotmail.com"
$From = "sss@hotmail.com@hotmail.com"
$Subject = "Running Services of the Server | $(get-date)"
$Smtpserver = "smtp.outlook.com"
$Port = 587
$Username = "sss@hotmail.com@hotmail.com"
$Password = ConvertTo-SecureString '*****' -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username, $Password
################################################
$Header =@"
<style>
h2 {
font-family: Arial, Helvetica, sans-seriff;
color: #000099;
font-size: 16px;
}
table {
border-width: 1px; border-style: solid; border-color: black; border-collapse:
collapse;
}
td {
border-width: 1px; padding: 3px; border-style: solid; border-color: black; text-allign:
center;
}
.ExpectedResolution {
color: #008000;
}
.NotExpectedResolution {
color: #ff0000
}
th {
background: #395870;
background: linear-gradient( #49708f, #293f50);
border-width: 1px; padding: 3px; border-style: solid; border-color: black; text-allign:
color: #fff;
font-size: 11px;
text-transform: uppercase;
padding: 10px 15px;
vertical-allign: middle;
}
tbody tr:nth-child(even){
background: #f0f0f2;
vertical-allign: middle;
}
#creationDate
{
font-family: Arial, Helvetica, sans-seriff;
color: #ff3300;
font-size: 12px;
}
}
</style>
"@
##################getting last reboot time####################
$arr = @()
#$servers = get-content 'E:\server.txt'
$servers= "Desktopname"
foreach ($Server in $servers)
{
$chk = Invoke-Command -ComputerName $Server {(Get-Service | Where-Object {$_.Status -EQ āRunningā})} |
Select-Object -Property status, name, displayname
$arr += (New-Object psobject -Property @{
status = $chk.status
name = $chk.name
displayname = $chk.displayname
})
}
$arr
$ResolutionReport = $arr | select status, name, displayname | ConvertTo-Html -Property status, name, displayname -Fragment -PreContent "<h2>Running Services</h2>"
$Report = ConvertTo-Html -Body "$ResolutionReport" -Head $Header -PostContent "<p id='CreationDate'>Creation Date : $(Get-Date)</p>"
############This command will generate the report to an HTML File##########################################
$Report | out-file 'E:\Lastupboot.html'
###########Sending Email To Recepients############################
$body1= Get-Content 'E:\Lastupboot.html' -Raw
$Body =
@"
<html><body></br>
Please find the running services of all the servers.
<html><body></br>
$body1
<br>
Regards
</br>
SSSSS
</body></html>
"@#>
Send-MailMessage -To $To -From $From -Subject $Subject -Body $Body -BodyAsHtml -SmtpServer $Smtpserver -Port $Port -UseSsl -Credential $Credential
#Send-MailMessage -To $To -From $From -Subject $Subject -Body $Body -BodyAsHtml -SmtpServer $Smtpserver -Port $Port -UseSsl
One great way to troubleshoot shorter scripts like this is to manually go through the script and run each line and check the output of your vars to see if you can track down when the expected output changes. I did this with your code and was able to track down the issue within a few seconds.
The problem primarily lies on this line and really, the code before it; and how the $arr
array object is being built:
$ResolutionReport = $arr | select status, name, displayname | ConvertTo-Html -Property status, name, displayname -Fragment -PreContent "<h2>Running Services</h2>"
If you manually run that code, youāll see the output of that object has the system.object, which is because itās in the $arr
array you created to store it in. This is because youāre taking output from each server and putting into an object, so youāre going to X amount of objects, where X is equal to the server youāre running the command on, and then your going to have a ton of āsubā objects, which are all the running servers.
As for a fix - it depends really on how you want the output to be. I think thereās some additional steps that could be simplified, especially after the data collection. Those are something I suggest looking at, as the forum isnāt really meant for us to re-write the code for you.
One way to address the problem though is by making some adjustments to treat each āserviceā as an object to report on, then add the hostname to it, and then you can keep it as a single report. Just taking a quick stab at that section Iād probably re-write it to something like this and adjust as needed:
$arr = New-Object System.Collections.Arraylist
#$servers = get-content 'E:\server.txt'
$servers = "Desktopname"
$chk = Invoke-Command -ComputerName $servers { Get-Service | Where-Object { $_.Status -EQ āRunningā } }
$chk | ForEach-Object {
$Obj = [PSCustomObject]@{
Status = $_.Status
Name = $_.Name
DisplayName = $_.DisplayName
HostName = $_.PSComputerName
}
$arr.add($obj) | Out-Null
}
$ResolutionReport = $arr |
ConvertTo-Html -Property status, name, displayname, hostname -Fragment -PreContent "<h2>Running Services</h2>"
$Report = ConvertTo-Html -Body "$ResolutionReport" -Head $Header -PostContent "<p id='CreationDate'>Creation Date : $(Get-Date)</p>"
This just my 10 minute fix thereās probably a ton of different ways to do it. In most cases like this I prefer to use ForEach-Object
over the foreach keyword
and for each āserviceā running I created an object to add to your original array that is ultimately being converted to HTML. I also added the hostname (or rather, the computer name of the service that is running) as youāll likely need that when taking this approach. I also modified the initial array to a generic list to gain access to the add method, which I find more intuitive in a lot of situations. This will fix the data so that when you convert it to html and the output will be a table with status, name, displayname, and hostname as the headers. Thereās definitely other optimizations/changes that could be made, but for now, Iām gonna stop there :).
Quick Edit: instead doing the invoke as part of the loop, i moved it up and used the original var. reads a little easier.
Great analysis and great improvement of the code.
As an aside: you actually donāt need a loop. The parameter -ComputerName
of the cmdlet Invoke-Command
can take an array of computer names.
And even if you use a loop you donāt need an [Arraylist]
when you simply capture the output of the loop in a varaible. PowerShell will create an array automatically.
Ah yep, youāre 100% right on the invoke-command this is why I hate responding to things on forums, because I would usually sit down and think about it some more other than just re-writing whatās there haha
Donāt worry. It will work anyway.
And at least when you need a check if the servers are online you will need a loop again.
I am thankful to everyone for the help . script is working fine . i am new to powershell so want to explore more things
thank you sir , really appreciated for your help and time