Powershell System Monitor – Monitor Disk Space, CPU, and Memory Utilization


Donate

Here is a new version of the system monitor, it is much more polished than the last version. It now includes email notifications if the disk space, CPU utilization or memory utilization goes above a point you specify in the configuration file. I personally recommend using this with Windows Scheduler. In the advanced menu, you can specify how often it recurs (in minutes). If any one is interested leave me a comment and I will post Reporting Services report for the different metrics.It is a work in progress, if you want something that will work. It is in the link below.  To set it up for your environment, modify the following files with the information you want to use:

  • systemmonitorconfiguration.ps1
  • systemmonitor.ps1 (modify the path currently [C:\PS1\SystemMonitor], to the path you are storing all of the scripts)
  • systemmonitordbscript.sql

To run the script in Powershell,  navigate to where the scripts are stored and run .\systemmonitor.ps1 with any combination of the following arguments:  disk, cpu, memory, email, post

Note: the post argument will only work if you have successfully setup the System Monitor database using the systemmonitordbscript.sql that has been configured for your environment.

Read the end user license agreement prior to using these scripts.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR “AS IS” AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

SystemMonitor.zip
Disk Space Report Note, you will have to change the report’s datasets to point to the server that has the database stored on it.
If you found this useful, subscribe.

4/27/2015 Fixed the broken links to the files, sorry folks!

1/27/2012 Update: I recently fixed the error [Cannot convert value “” to type “System.Boolean”, parameters of this type only accept booleans or numbers, use $true, $false, 1 or 0 in stead.. Please check back soon as I will be cleaning up the two “errors”]. The revised code is now the current link.

7/11/2012 Update: I added a new feature to notify you if service(s) stops. It will also attempt to restart the service if you choose within the configuration file. Currently it does not post to the database as I do not see much need for it but let me know what you think.

1/30/2012 Update: The zip now includes a SSRS report for disk space.

If you would like to contribute let me know and I would be happy to give you credit and collaborate with you. Just post a comment and I will get back to you.

Advertisement

24 thoughts on “Powershell System Monitor – Monitor Disk Space, CPU, and Memory Utilization

  1. Just out of curiosity, how are you starting the script in Powershell? If you are starting the script by just running .\systemmonitor.ps1 that is the default message. But if you do something like .\systemmonitor.ps1 cpu it will trigger the system to explicitly call it. The arguments you can call are cpu, memory, and disk. This is handy if you want to check things at different intervals.

  2. I just like the helpful info you supply in your articles. I will bookmark your blog and take a look at once more here frequently. I’m relatively certain I?ll be told lots of new stuff right right here! Best of luck for the next!

  3. Getting error:

    Exception calling “Open” with “0” argument(s): “The ConnectionString property has not been initialized.”
    At C:\SystemMonitor\SystemMonitorHistory.ps1:4 char:24
    + $sqlcom.Connection.Open <<<< ()
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    Exception calling "ExecuteReader" with "0" argument(s): "ExecuteReader requires an open and available Connection. The c
    onnection's current state is closed."
    At C:\SystemMonitor\SystemMonitorHistory.ps1:9 char:69
    + [System.Data.SqlClient.SqlDataReader]$sqlrdr = $sqlcom.ExecuteReader <<<< ()
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    You cannot call a method on a null-valued expression.
    At C:\SystemMonitor\SystemMonitorHistory.ps1:17 char:15
    + $sqlrdr.Close <<<< ()
    + CategoryInfo : InvalidOperation: (Close:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    Exception calling "ExecuteNonQuery" with "0" argument(s): "ExecuteNonQuery requires an open and available Connection. T
    he connection's current state is closed."
    At C:\SystemMonitor\SystemMonitorHistory.ps1:19 char:41
    + $rowsAffected = $sqlcom.ExecuteNonQuery <<<< ()
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    Exception calling "ExecuteScalar" with "0" argument(s): "ExecuteScalar requires an open and available Connection. The c
    onnection's current state is closed."
    At C:\SystemMonitor\SystemMonitorHistory.ps1:21 char:35
    + $serverID = $sqlcom.ExecuteScalar <<<< ()
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    0 server have been added.
    Exception calling "ExecuteScalar" with "0" argument(s): "ExecuteScalar requires an open and available Connection. The c
    onnection's current state is closed."
    At C:\SystemMonitor\SystemMonitorHistory.ps1:30 char:32
    + $count = $sqlcom.ExecuteScalar <<<< ()
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    Exception calling "ExecuteScalar" with "0" argument(s): "ExecuteScalar requires an open and available Connection. The c
    onnection's current state is closed."
    At C:\SystemMonitor\SystemMonitorHistory.ps1:30 char:32
    + $count = $sqlcom.ExecuteScalar <<<< ()
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    Exception calling "ExecuteScalar" with "0" argument(s): "ExecuteScalar requires an open and available Connection. The c
    onnection's current state is closed."
    At C:\SystemMonitor\SystemMonitorHistory.ps1:30 char:32
    + $count = $sqlcom.ExecuteScalar <<<< ()
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

      • Hello John,

        Thanks for help, but I don’t know how to define connection string.

        If you can guide on configuration steps to use “SystemMonitor” PowerShell tool, it will help me a lot.

        Thanks

      • So the first thing you will want to do is run the SQL file against a SQL Server 2005 or above to create the database that will hold the history. Next, you will want to change the configuration file with the settings specific to your environment. You will want to plug in connection string: Data Source=myServerAddress;Initial Catalog=myDataBase;User Id=myUsername;Password=myPassword; replacing everything on the right side of the equals with specifics of the SQL Server you are using. Lastly, you will want to change the path: $env:Path += “;C:\PS1\SystemMonitor” to the place where you put all the files. Please note you need to keep the semi-colon at the beginning of the string. Also you will want to save each file locally on the computer. Powershell’s security prevents you from running scripts from the internet if your execution policy is set to remote signed, saving each file through notepad will get around this. Also, I recommend setting your execution policy in Powershell to remotesigned.

      • Also, if you would rather not save the data, you can also turn it off by modifying the configuration file, line 12, to this [Bool] $post = $false and also not use the post argument.

  4. Hi John, Looks nice this setup. How about including a script to monitor services??? I got one that does it for services marked as automatic and sends an alert if is not in the state “running”.

  5. …and somewhere I read that you could arrange for reporting services reports…
    …that would be really cool !!!

    • Thanks for reminding me, I had the reports developed but greedily keeping them to myself. I will put them up in the next couple of days. I also like the idea of alerting for inactive services. I will start working on that next week and post it.

      • to help you along with the services part…
        Heres the code i put together…

        #############
        cls
        $ServerList = Get-Content “D:\SysAppz\ServiceMonitorChecks\servers.txt”
        $report = “report.htm”
        Clear-Content $report
        Add-Content $report “”
        Add-Content $report “”
        Add-Content $report “”
        Add-Content $report ‘MultiServer Failed Service Report’
        add-content $report ”
        add-content $report “”
        add-content $report “”
        Add-Content $report “”
        Add-Content $report “”
        add-content $report “”
        add-content $report “”
        add-content $report “”
        add-content $report “MultiServer Failed Service Report
        add-content $report “”
        add-content $report “”
        add-content $report “”

        add-content $report “”
        Add-Content $report “”
        Add-Content $report “Server Name”
        Add-Content $report “Failed Service Name”
        Add-Content $report “Status”
        Add-Content $report “”
        $serviceDownCount = 0
        foreach ($machineName in $serverlist)
        {
        $serviceStatus = get-WmiObject win32_service -ComputerName $machineName `
        -Filter “StartMode=’Auto’ and State’Running’ and not (Name like ‘clr_optimization%’ or Name like ‘BTSsvc%’ or Name like ‘MSSQL%’ or Name like ‘SQLAgent%’ or Name like ‘ENTSSO’ or Name like ‘MsDts%’ or Name like ‘MSOLAP%’ or Name like ‘ReportServer%’ or Name like ‘RuleEngineUpdateService’or Name like ‘ShellHWDetection’or Name like ‘sppsvc’)” |
        select name, State, @{l=”machineName”;e={$machineName}}
        if ($serviceStatus -ne $null)
        {
        foreach ($service in $serviceStatus)
        {
        Write-Host $machineName `t $service.name `t $service.state -ForegroundColor Red
        $svcName = $service.name
        $svcState = $service.state
        Add-Content $report “”
        Add-Content $report “$machineName”
        Add-Content $report “$svcName”
        Add-Content $report “$svcState”
        Add-Content $report “”
        $serviceDownCount += 1
        }
        }
        else
        {
        Write-Output “All Automatic Services on $machinename are running.”
        }
        }
        Add-content $report “”
        Add-Content $report “”
        Add-Content $report “”
        Write-Output $serviceDownCount
        if ($serviceDownCount -ge 1)
        {
        $smtphost = “mailrelay”
        $from = “sysinfo@company.com”
        $to = “serversupport@company.com”
        $subject = “Failed Service Monitor Report”
        $body = Get-Content $report
        $smtp= New-Object System.Net.Mail.SmtpClient $smtphost
        $msg = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body
        $msg.isBodyhtml = $true
        $smtp.send($msg)
        }

        #############
        this is a fancy script that will email and put “failed” content into the mail body.
        Hope it helps.

  6. This is a great piece of work. Many many thank yous. One question, If I wanted to run this against a txt file of server names how would I modify SystemMonitorInitialization.ps1 to look at a text file with a list of servernames instead ok the local machine?

    I tired to modify the first line….
    [String]$computer = Get-Content -Path (C:\LOAD\Load_Stuff\MonitoringScripts\Env2_TS_Servers.txt).value

    but it is bombing out with the following error…

    At C:\LOAD\SystemMonitor\SystemMonitorInitialization.ps1:17 char:30
    + ForEach ($server in $servers)
    + ~
    Missing statement body in foreach loop.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : MissingForeachStatement

    Many thank yous,

    Rob

    • Hi Rob,

      I don’t think what you are trying to do is going to work easily on this script. The reason that I say that is because of an architecture decision I made originally before writing the scripts. I made the decision that it would be more reliable if the scripts were installed on each computer. Having one central server monitoring all of them would mean that there was a single point of failure which I wanted to avoid.

      I have less important scripts that are running to see statuses of jobs which are run from my desktop PC to make sure everything worked completely. It works well for what I am doing and I might even post them at some point on here.

      For the specific error you are getting though. I would recommend something like this:
      [String]$computers[] = Import-CSV

      Where the file is a list of computer names, one per line. This way you will have an array of computer names to iterate against. However, I still am pretty sure you will have some issues elsewhere.

  7. Thanks for helping everyone who is looking for something very similar to these scripts.
    Are all these files dependant on each other? Can I run any one at any time? Or is there any particular file to be ran during the beginning?

    • Hi Bhoomi,

      Your welcome, I figured a lot of people out there were needing something like this. Here is deal:

      If you want to get the disk information by running SystemMonitorDiskSpace.ps1. You can call the $disks which will return the disk information. If you want to always return the disk information from that script, you can add a new line to the end of the script that just says $disks or you could do something like $disks | format-list.

      You can do the exact same thing for SystemMonitorMemory. The variable to use is $memstats.

      Also for SystemMonitorProcessor, the variable is $processors.

      SystemMonitorService at this time is not capable of running independently, but with a little modification, it could.

      Hope it works well for what you need.

  8. Thanks for this great content. I really enjoyed it lots.
    What you have done is actually really inspirational.

    |
    This is really inspirational content. I would like to use your style
    to improve my own content on my blog.

Have an opinion? Leave an opinion!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s