Reading Time: 4 minutes, 26 secs

PowerShell: How to easily create log files for your scripts

Today I thought I would share some thing that I have developed over the last year or so as I have been working more and more with PowerShell…. some standard functions that can simply be dot sourced and called at any time so that all my scripts have some awesome logs to go along with the awesome script.

Why have logging?

Well personally I feel that this is a very important part of a script or tool that is developed, particularly if it is going to be used regularly and provides some sort of valuable functionality.

Having a log that people can follow, and see what is happening while the script is executing or if the script runs into errors is very useful. Not only that, but I feel people will respect your developed scripts \ tools as they see it as a mature product, not some dodgey back-yard operation that was just copied from the web and had the crap hacked through it.

The other reason is that it makes troubleshooting a hell of a lot easier… particularly 6 – 12 months down the track when lets say you are running the script in a different environment than what it was originally developed for. Having a log and being able to write out the result of each step of your script allows you to easily pin-point where the problem lies, especially if you pipe out error messages to the log (both custom or system errors).

Another great reason is having compassion on the guy the might be having to update or troubleshoot your script \ tool in the future. Its sort of like having well commented code (which I know everyone does… lol), it makes it easier for someone to be able to track your script and know what is happening and why its happening.

Finally, the reason why I personally like logging is because the way I layout all of my scripts is a seperate function per major task that the script completes. At the end of my scripts I then have an execution section where I call all of my functions in order and pass the required variables.

Using logging with this approach to development is great because it allows you to break your log into sections… each function has its own mini log section if you like, so it makes tracking the script really really easy and plus it looks awesome.

Logging Function Library: The contents

Becuase of the reasons above, I decided to create a logging function library which is essentially just a .ps1 file with a bunch of standard log functions. In each of my scripts I just dot source the .ps1 file and then call the each of the functions as required. The functions included in logging library are:

  • Log-Start: Creates the .log file and initialises the log with date and time, etc
  • Log-Write: Writes a informational line to the log
  • Log-Error: Writes an error line to the log (formatted differently)
  • Log-Finish: Completes the log and writes stop date and time
  • Log-Email: Emails the content of the log

Logging Function Library: Log Formatting

All of my scripts use this logging library and therefore all the logs look kinda the same. This is actually a good thing because it allows your user base to get used to a particular log format and so its just another incentive for them to use and enjoy your script that you worked so hard on.

Here is a screenshot of one of my logs that has been written using this logging function library

PowerShell Log Example 520x307 PowerShell: How to easily create log files for your scripts

Logging Function Library: The Code

Ok guys, enough rampling… here it is in all of its raw beauty:

Logging Function Library: Installation Instructions

Here are the instructions to start using this logging function library in your scripts:

  1. Copy the code above and save it in a new .ps1 file called “Logging_Functions.ps1″. Alternatively you can download the file from here: PowerShell Logging Function Library
  2. Copy the file and store it in a central location that everyone has access to (Note: This is very important otherwise your script will fail for people who don’t have access to the function library)
  3. In your script dot source the Logging_Functions.ps1 file. You should do this at the top of your PowerShell script and it should look something like this:
    		. "C:\Scripts\Functions\Logging_Functions.ps1"
    		
  4. Call the relevant functions as required (see the examples found in the meta information of each of the functions on how to do this)

PowerShell Script Template

If you are unsure on how to do step 4 above, or you would like to fill-out a standard template that have everything you need to create a new PowerShell script, then check out this post: PowerShell Script Template

If you have any problems using my PowerShell Logging Function Library then please let me know in the comments below or send me an email and I will try my hardest to get you all fixed up. Also, if you have any cool ideas or have some thoughts on how to improve the library then I am always intersted in hearing what others are doing and how I can improve myself.

Thanks guys and happy scripting icon smile PowerShell: How to easily create log files for your scripts

Luca

5 Likes
20 Comments.
  1. Kosta

    Hello, i am trying to use it in other script so i state:
    . “D:\scripts\Functions\Logging_Functions.ps1″
    Log-Start -logPath “D:\scripts\log” -LogName “service_check.log”

    but immediately when the script starts i get this error message:

    New-Item : Access to the path ‘D:\scripts\log’ is denied.
    At D:\scripts\Functions\Logging_Functions.ps1:53 char:17
    + New-Item <<<< -Path $LogPath -Value $LogName -ItemType File
    + CategoryInfo : PermissionDenied: (D:\scripts\log:String) [New-Item], UnauthorizedAccessException
    + FullyQualifiedErrorId : NewItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.NewItemCommand

    I wonder why it has no access as it already written the log header.

    Thank you,
    Kosta

    • Luca Sturlese

      Hi Kosta,

      Thanks for the comment and I am glad that you are using the logging script.

      I had a look and line 53 is this “New-Item -Path $LogPath -Value $LogName –ItemType File”, which is the line that will create the log file, so in your case it is trying to create service_check.log file in D:\Scripts\Logs directory. Can you confirm that the context in which the script is running has at least modify permissions to this directory? Also can you have a look in the directory and see if the script actually creates the log file?

      The other thing I would try is create a test script using my PowerShell Script Template and see if you get the same error again.

      Hope this helps. If you still can’t figure it out, let me know the answers to the above questions and we can go from there.

      Thanks
      Luca

      • Andy

        The problem is with the line below and the -Value parameter
        New-Item -Path $LogPath -Value $LogName –ItemType File

        it should be -Name as below.
        New-Item -Path $LogPath -Name $LogName –ItemType File

        Other than that. Great re-usable scripts

        • Luca Sturlese

          Hi Andy,
          You are correct it should be -Name and now -Value. Strangely enough I am pretty sure that the Value parameter did work for me in the past but that might have been on a previous version of PowerShell (such as version 2).
          In any case, thanks very much for picking that up, I have now updated the code in the article.
          Thanks again
          Luca

  2. Caleb

    Hi Andy,

    Love the script. i’m using in most of mine scripts, Thanks
    Would it be possible to make it so that each time the script that calls the log function it adds to a previous log file and does not overwrite it?

    • Luca Sturlese

      Hi Caleb,

      Sorry about the late reply. Yes this is possible. In the Logging Function Library file just remove the following lines from the Log-Start function:


      #Check if file exists and delete if it does
      If((Test-Path -Path $sFullPath)){
      Remove-Item -Path $sFullPath -Force
      }

      Hope this helps

      Luca

  3. Matthew

    Thanks for the template and library. Is there a way with this to output into the log a stream? I”m trying to backup GPO’s and want it to actually output the results of the command using your template:

    Backup-GPO -All -Path $sPath

    Thanks. (I’m new to Powershell so still learning the ropes).

    • Luca Sturlese

      Hi Matthew,

      I am not 100% sure what you are asking but if you would like to print the log items out to screen as opposed to a text file you can use the cmdlet Write-Debug.

      As an example you can try this >>> Write-Debug "Hellow World". This should print this to the screen.

      Let me know if this is what you are after.

      Thanks
      Luca

  4. Caleb

    Hi Luca,

    And i’m sorry about my last message, Accidentally attention-ed it to the wrong person.
    Thank you for that, i am using this in every one of my scripts now!!!

    Regards
    Caleb

    • Luca Sturlese

      Hi Caleb,

      Thanks very much for the positive feedback and glad that you are using it… that is awesome!

      Regards
      Luca

  5. Albert

    Hi, that’s a wonderful, but i’m not pretty sure how to implement this script in my function in order to output the possible errors that could appear while executing the function. Could you help me??

    For example, If I want to include your function in a for each, how I have to call to your function??

    Thanks,

    • Luca Sturlese

      Hi Albert,

      Thanks for commenting. Take a look at my PowerShell Script Template because this gives you a template to build your scripts on using the PowerShell Logging Function Library. So for example if you want to write an information line into your log you would use the following Log-Write -LogPath $sLogFile -LineValue "...".

      If you would like to write an error to the log then use this Log-Error -LogPath $sLogFile -ErrorDesc "Error description goes here" -ExitGracefully $True. The best way to use the error logging function would be with using one of the error handling options available in PowerShell. The one that I find most useful and that I use (and is documented in the PowerShell Script Template) is Try… Catch. Have a look at the PowerShell Script Template post and it is all documented there.

      If you still stuck, just let me know and I can help you out.

      Thanks
      Luca

  6. Casper

    Hi Luca,

    I would like to know how to use Log-Error. For Example I got line in script:

    Import-Clixml d:\something.xml and when imported file doeasnt existx i got error. I can use

    Log-Write -LogPath $LogFile -LineValue ($error[0] | out-string)

    But how to use Log-Error? All my tryes end with:

    Log-Error : Cannot bind argument to parameter ‘ErrorDesc’ because it is an empty string.
    At D:\SKRIPTS\POWERSHELL\Create_User_in_AD.ps1:19 char:40
    + Log-Error -LogPath $LogFile -ErrorDesc $_.Exception -ExitGracefully $True
    + ~~~~~~~~~~~~
    + CategoryInfo : InvalidData: (:) [Log-Error], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Log-Error

    Thank you.

    • Luca Sturlese

      Hi Casper,

      Can you show me the exact line of code you are having trouble with?

      What I would do is try something like this:


      $sError = $Error[0] | Out-String
      Log-Error -LogPath $sLogFile -ErrorDesc $sError -ExitGracefully $True

      Give that a go and see if that works.

      Thanks
      Luca

  7. Manuel

    Hi Luca
    This is a very useful function library, thanks a lot. I will use it in all my new scripts :-)
    Manuel

  8. Mohammad Taha

    I have this error
    Log-Error : Cannot bind argument to parameter ‘ErrorDesc’ because it is an empty string.

    i tried to use $Error and $error[0] and $sError = $Error[0] | Out-String
    but no Luke could you please help

    • Luca Sturlese

      Hi Mohammad,

      Can you please send through via email or reply to this post and extract of your code so I can see what is happening?

      Thanks
      Luca

  9. sagar

    Lucas,
    Even after removing the below script, I am still not able to append the data to the log file. It fails saying the log file already exists.

    #Check if file exists and delete if it does
    If((Test-Path -Path $sFullPath)){
    Remove-Item -Path $sFullPath -Force
    }
    Also I am trying to capture the error and using the function log-error, but i cannot capture the error…
    try{
    Invoke-Sqlcmd -query “select top 10 * from sales”
    Log-Write -LogPath $sLogFile -LineValue “step 2-altered the table : $tblname”
    }
    catch
    {
    write-output(“starting catch block”)
    Log-Error -LogPath $sLogFile -ErrorDesc $sError -ExitGracefully $True
    Break
    }
    If that table doesn’t exist i want to capture that error. But it’s displaying on the ps screen without capturing it.

  1. By PowerShell Script Template | 9to5IT on February 19, 2013 at 11:07 pm

    [...] I recently put up an article on how to easily create log files in PowerShell. If you want to read that post, then check out this link – PowerShell: How to easily create log files for your scripts. [...]

Leave a Comment.