Share via


Script Not Working As Expected When Scheduled

Question

Monday, July 13, 2020 10:14 AM

Hi Guys,

I have an odd issue with a PowerShell Script, if i run it from the PowerShell ISE it generates the HTML File Correctly with all the results displayed. 

For some reason when I run it with task scheduler it only displays the result of $CloudBackup..

Can anyone see what I have done wrong? Script below

function Write-HTML{
<#
.CREATED BY:
    Christopher Wager
.CREATED ON:
    22/05/2020
.SYNOPSIS
    Creates an HTML file on the Desktop of the local machine full of detailed system information.
.DESCRIPTION
    Write-HTML utilizes WMI to retrieve information related to the physical hardware of the machine(s), the available `
    disk space, when the machine(s) last restarted and bundles all that information up into a colored HTML report.
.EXAMPLE
   Write-HTML -Computername localhost,
   This will create an HTML file on your desktop with information gathered from as many computers as you can access remotely
#>
      [CmdletBinding(SupportsShouldProcess=$False)]
param([Parameter(Mandatory=$false,
      ValueFromPipeline=$true)]
      [string]$FilePath = "C:\Report\Report.html",
      [string[]]$Computername = $env:COMPUTERNAME,
$Css='<style>table{margin:auto; width:98%}
              Body{background-color:#DCD2FF; Text-align:Center;}
                th{background-color:black; color:white;}
                td{background-color:Grey; color:Black; Text-align:Center;}
     </style>' )

Begin{ Write-Verbose "HTML report will be saved $FilePath" }

Process{ $Hardware = Get-WmiObject -class Win32_ComputerSystem -ComputerName $Computername | 
         Select-Object Name,Domain,Manufacturer,Model,NumberOfLogicalProcessors,
         @{ Name = "Installed Memory (GB)" ; Expression = { "{0:N0}" -f( $_.TotalPhysicalMemory / 1gb ) } } |
         ConvertTo-Html -Fragment -As Table -PreContent "<h4>Hardware</h4>" | 
         Out-String;

$PercentFree = Get-WmiObject Win32_LogicalDisk -ComputerName $Computername | 
               Where-Object { $_.DriveType -eq "3" } | Select-Object SystemName,VolumeName,DeviceID,
               @{ Name = "Size (GB)" ; Expression = { "{0:N1}" -f( $_.Size / 1gb) } },
               @{ Name = "Free Space (GB)" ; Expression = {"{0:N1}" -f( $_.Freespace / 1gb ) } },
               @{ Name = "Percent Free" ; Expression = { "{0:P0}" -f( $_.FreeSpace / $_.Size ) } } |
               ConvertTo-Html -Fragment -As Table -PreContent "<h4>Available Disk Space</h4>" | 
               Out-String;

$DiskHealth = Get-PhysicalDisk -DeviceNumber 0 |
              Select-Object FriendlyName, OperationalStatus, HealthStatus |
              ConvertTo-Html -Fragment -PreContent "<h4>Physical Disk Health</h4>" |
              Out-String;
    
$Restarted = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $Computername | Select-Object Caption,CSName,
             @{ Name = "Last Restarted On" ; Expression = { $_.Converttodatetime( $_.LastBootUpTime ) } } |
             ConvertTo-Html -Fragment -As Table -PreContent "<h4>Last Boot Up Time</h4>" | 
             Out-String;

$Stopped = Get-WmiObject -Class Win32_Service -ComputerName $Computername | 
           Where-Object { ($_.StartMode -eq "Auto") -and ($_.State -eq "Stopped") } |
           Select-Object SystemName, DisplayName, Name, StartMode, State, Description |
           ConvertTo-Html -Fragment -PreContent "<h4>Autostart Services That Are Currently Stopped.</h4>" | 
           Out-String;

$CloudBackup = Get-WinEvent -FilterHashtable @{logname='CloudBackup'; id=1,3,11} -MaxEvents 1 |
               Select-Object Message, TimeCreated |
               ConvertTo-Html -Fragment -PreContent "<h4>Azure Backup.</h4>" |
               Out-String;

$Report = ConvertTo-Html -Title "$Computername" `
                         -Head "<h4>System Health Reporting<br><br>$Computername</h4><br>This report was ran: $(Get-Date)" `
                         -Body "$Restarted $DiskHealth $PercentFree $CloudBackup $Stopped $Css" }

End{ $Report | Out-File $Filepath ; Invoke-Expression $FilePath }
}
Write-HTML

<# This Section of the Script will email the result, using the SMTP Service installed on the localhost. #>

############################################################################### 
 
###########Define Variables######## 
 
$fromaddress = "[email protected]
$toaddress = "[email protected]"
<# $ccaddress = "[email protected]" #>  
$Subject = "Health Report" 
$body = "Attached is the Health Report for HISSWDC01"
$attachment = "C:\Report\Report.html" 
$smtpserver = "localhost" 
 
#################################### 
 
$message = new-object System.Net.Mail.MailMessage 
$message.From = $fromaddress 
$message.To.Add($toaddress)
$message.CC.Add($ccaddress) 
$message.IsBodyHtml = $True 
$message.Subject = $Subject 
$attach = new-object Net.Mail.Attachment($attachment) 
$message.Attachments.Add($attach) 
$message.body = $body 
$smtp = new-object Net.Mail.SmtpClient($smtpserver) 
$smtp.Send($message) 
$message.Dispose()  
$attach.Dispose() 

#################################################################################

All replies (7)

Monday, July 13, 2020 12:53 PM | 1 vote

Add a Start-Transcript command so that you can get a log of the commands being executed and any errors that it encounters. 

Get-Help Start-Transcript -examples

Monday, July 13, 2020 2:52 PM

Does it work if you run the script from a PowerShell console (i.e. not from ISE)? Does your scheduled execution run with the same account and privilege as it has when you run it from the ISE?

Also, when you supply code as an example, use the "Insert Code Block" icon (the one that's probably second from the left) that looks like a small square with "<>" in it.

You can try putting each of your data gathering pieces in a Try/Catch and if there's a problem have the Catch block put the error into the variable (just be sure to add "-ErrorAction STOP" to Get-WmiObject, Get-PhysicalDisk, and Get-WinEvent cmdlets - without that the Catch block won't be triggered).

Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)


Monday, July 13, 2020 4:16 PM

Tasks in task manger have no desktop so the script cannot be used.

Please understand that this forum is not for fixing or modifying script s you have found on the Internet.  This is not a help desk or customer service forum.

Please carefully review the following links to set your expectation for posting in technical forums.

\(ツ)_/


Monday, July 13, 2020 6:39 PM

Okay, so there's no $env from which to get values.

I can understand that as the cause for the Get-WmiObject cmdlets (the $ComputerName parameter won't have a value), but why would that have an effect on the Get-PhysicalDisk cmdlet?

Unless he omitted something (the $DiskHealth variable), he said only the $CloudStorage variable had a value.

Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)


Tuesday, July 14, 2020 10:26 AM

Don't worry about it, I will consult with a contact of mine from another company since I have clearly done something that is against the rules based on the comment from the moderator its probably best to let this one go dead.

Although for anyone that is interested the script works fine the issue was actually Comodo AEP - Auto Containment. 

Never thought to look there until someone else suggested it.


Tuesday, July 14, 2020 1:36 PM

Don't worry about it, I will consult with a contact of mine from another company since I have clearly done something that is against the rules based on the comment from the moderator its probably best to let this one go dead.

Although for anyone that is interested the script works fine the issue was actually Comodo AEP - Auto Containment. 

Never thought to look there until someone else suggested it.

This is common when you have little or no knowledge of the technology you are asking about.  We cannot do customer service on your systems,  The forum is for techs who have learned PowerShell and have questions about scripts they have written.

When trying to solve issues with technology it is usually best to contact the vendor of the system at issue.  In this case you seem to have now discovered that the system under inspection or the executing system is the source of your issues.  There is not way anyone could have guessed this.

These issue are why the forum warns about asking for help with scripts found, discovered, copied or received from a vendor.

We are glad you discovered the source of your issue.

For untrained users it is always best to contact a consultant.  If you are acting as tech-for-hire then you should already know these things.

\(ツ)_/


Tuesday, July 14, 2020 1:36 PM

The issue, if there is any, is that we get a lot of Magic Crystal Ball questions. Someone posts a script and asks "why doesn't this work?". No error message, no description of the environment, no details of the parameters passed to the script, no comment on the account the script is running as, etc, etc.

The best we can do is eyeball the script and guess as to what the problem might be. The .SYNOPSIS comment mentions the desktop, but $filepath is set to C:\Report\Report.html. Since we don't know what account the task is running as, we don't know if it has access and if that's a problem or not. 

I don't see anywhere in your script where it references Comodo AEP. How would we know that was even a potential problem? We can't be expected to troubleshoot scripts where we have no idea of all the other "stuff" that impacts script execution.  

Your best option is to generate a transcript. That will log the environment and any errors that it encounters. You need 2 statements to start and stop it. 

Start-Transcript C:\temp\foo.log           ###### Begin transcript
Write-HTML

<# This Section of the Script will email the result, using the SMTP Service installed on the localhost. #>

############################################################################### 
 
###########Define Variables######## 
 
$fromaddress = "[email protected]" 
$toaddress = "[email protected]"
<# $ccaddress = "[email protected]" #>  
$Subject = "Health Report" 
$body = "Attached is the Health Report for HISSWDC01"
$attachment = "C:\Report\Report.html" 
$smtpserver = "localhost" 
 
#################################### 
 
$message = new-object System.Net.Mail.MailMessage 
$message.From = $fromaddress 
$message.To.Add($toaddress)
$message.CC.Add($ccaddress) 
$message.IsBodyHtml = $True 
$message.Subject = $Subject 
$attach = new-object Net.Mail.Attachment($attachment) 
$message.Attachments.Add($attach) 
$message.body = $body 
$smtp = new-object Net.Mail.SmtpClient($smtpserver) 
$smtp.Send($message) 
$message.Dispose()  
$attach.Dispose() 
Stop-Transcript        ###### End transcript

Obviously I'm going to get a lot of errors. 

**********************
Windows PowerShell transcript start
Start time: 20200714092620
Username: SLICK\Dave
RunAs User: SLICK\Dave
Configuration Name: 
Machine: SLICK (Microsoft Windows NT 10.0.19041.0)
Host Application: C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe
Process ID: 16680
PSVersion: 5.1.19041.1
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.19041.1
BuildVersion: 10.0.19041.1
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
Transcript started, output file is C:\temp\foo.log
Get-WinEvent : There is not an event log on the localhost computer that matches "CloudBackup".
At line:60 char:16
+ ... oudBackup = Get-WinEvent -FilterHashtable @{logname='CloudBackup'; id ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (CloudBackup:String) [Get-WinEvent], Exception
    + FullyQualifiedErrorId : NoMatchingLogsFound,Microsoft.PowerShell.Commands.GetWinEventCommand
Get-WinEvent : There is not an event log on the localhost computer that matches "CloudBackup".
At line:60 char:16
+ ... oudBackup = Get-WinEvent -FilterHashtable @{logname='CloudBackup'; id ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (CloudBackup:String) [Get-WinEvent], Exception
    + FullyQualifiedErrorId : NoMatchingLogsFound,Microsoft.PowerShell.Commands.GetWinEventCommand

>> TerminatingError(Get-WinEvent): "The parameter is incorrect"
Get-WinEvent : The parameter is incorrect
At line:60 char:16
+ ... oudBackup = Get-WinEvent -FilterHashtable @{logname='CloudBackup'; id ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-WinEvent], EventLogException
    + FullyQualifiedErrorId : 
System.Diagnostics.Eventing.Reader.EventLogException,Microsoft.PowerShell.Commands.GetWinEventCommand
Get-WinEvent : The parameter is incorrect
At line:60 char:16
+ ... oudBackup = Get-WinEvent -FilterHashtable @{logname='CloudBackup'; id ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-WinEvent], EventLogException
    + FullyQualifiedErrorId : System.Diagnostics.Eventing.Reader.EventLogException,Microsoft.PowerShell.Commands.GetWinEventCommand

PS>TerminatingError(Out-File): "Could not find a part of the path 'C:\Report\Report.html'."
Out-File : Could not find a part of the path 'C:\Report\Report.html'.
At line:69 char:16
+ End{ $Report | Out-File $Filepath ; Invoke-Expression $FilePath }
+                ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OpenError: (:) [Out-File], DirectoryNotFoundException
    + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand
Out-File : Could not find a part of the path 'C:\Report\Report.html'.
At line:69 char:16
+ End{ $Report | Out-File $Filepath ; Invoke-Expression $FilePath }
+                ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OpenError: (:) [Out-File], DirectoryNotFoundException
    + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand

C:\Report\Report.html : The term 'C:\Report\Report.html' is not recognized as the name of a cmdlet, function, script 
file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct 
and try again.
At line:1 char:1
+ C:\Report\Report.html
+ ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Report\Report.html:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
C:\Report\Report.html : The term 'C:\Report\Report.html' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ C:\Report\Report.html
+ ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Report\Report.html:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Exception calling "Add" with "1" argument(s): "Value cannot be null.
Parameter name: item"
At line:95 char:1
+ $message.CC.Add($ccaddress)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentNullException
Exception calling "Add" with "1" argument(s): "Value cannot be null.
Parameter name: item"
At line:95 char:1
+ $message.CC.Add($ccaddress)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentNullException

>> TerminatingError(New-Object): "Exception calling ".ctor" with "1" argument(s): "Could not find a part of the path 'C:\Report\Report.html'.""
new-object : Exception calling ".ctor" with "1" argument(s): "Could not find a part of the path 
'C:\Report\Report.html'."
At line:98 char:11
+ $attach = new-object Net.Mail.Attachment($attachment)
+           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [New-Object], MethodInvocationException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
new-object : Exception calling ".ctor" with "1" argument(s): "Could not find a part of the path 'C:\Report\Report.html'."
At line:98 char:11
+ $attach = new-object Net.Mail.Attachment($attachment)
+           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [New-Object], MethodInvocationException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

Exception calling "Add" with "1" argument(s): "Value cannot be null.
Parameter name: item"
At line:99 char:1
+ $message.Attachments.Add($attach)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentNullException
Exception calling "Add" with "1" argument(s): "Value cannot be null.
Parameter name: item"
At line:99 char:1
+ $message.Attachments.Add($attach)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentNullException

Exception calling "Send" with "1" argument(s): "Failure sending mail."
At line:102 char:1
+ $smtp.Send($message)
+ ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException
Exception calling "Send" with "1" argument(s): "Failure sending mail."
At line:102 char:1
+ $smtp.Send($message)
+ ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

You cannot call a method on a null-valued expression.
At line:104 char:1
+ $attach.Dispose()
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At line:104 char:1
+ $attach.Dispose()
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

**********************
Windows PowerShell transcript end
End time: 20200714092652
**********************