Skip to main content

Creating an Error Log: Option 2 - Use an XML file

This is day 5 of how to create an error log.

I normally advocate the usage of XML files for storing data, but I’ll be honest.  I prefer CSV when it comes to my log files.  The ability to append to the file is why.  It makes coding so much easier.  We are going to look at what needs to be done if we want to use XML instead of CSV. 

XML cannot be appended to.  This means that if we want to keep the data from a previous execution, then we need to read it into an array.  We must then add a new instance to that array for each error that occurs and then write the entire array back to the error log at the end of the script.

Function Test-ADUsers
{
    [CmdletBinding()]
    Param (
        [parameter(Mandatory=$true)]
        [String[]]
        $Names,

        [Switch]
        $NoAppend

# Begin Support Functions
    )
    Function Test-ErrorLog
    {
    [CmdletBinding()]
    Param (
        [parameter(Mandatory=$true)]
        [String]
        $Path,

        [parameter(Mandatory=$true)]
        [String]
        $Name
        )

        # Test the path.
        If (!(Test-Path -Path $Path))
        {
            Write-Verbose "Creating the directory $Path"
            New-Item -Path $Path -ItemType Directory
        }

        # Test the file
        If (!(Test-Path -Path "$Path\$Name"))
        {
            Write-Verbose "Creating the file $Name"
            New-Item -Path "$Path\$Name" -ItemType File
        }

    } # END: Function Test-ErrorLog

# End Support Functions

    # Initialize the array to hold the XML data.
    $Data = @()

    # Verify that the error log is present.
    Test-ErrorLog -Path c:\ps\error -Name Errorlog.xml

    # If -NoAppend is TRUE, then clear the error log.
    If($NoAppend)
    {
        Write-Verbose "Clearing the error log"
        Remove-Item -Path C:\PS\error\ErrorLog.xml -Force
        New-Item -Path C:\PS\error -Name ErrorLog.xml -ItemType File     
    }
    Else
    {
        # Import in the XML data is we are appending to the origional file.
        $Data += Import-Clixml -Path C:\ps\error\Errorlog.xml
    }

    ForEach ($Name in $Names)
    {
        Try {Get-ADUser -Identity $Name -ErrorAction Stop}
        Catch
        {
        
            $Data += $Error[0]
        }
    }

    # Commit the XML data to Disk
    $Data | Export-Clixml -Path C:\ps\error\ErrorLog.xml
} # END: Function Test-ADUsers

Test-ADUsers -Names "Administrator", "Bad", "Administrator"

We made a few changes.  First off, we initialize an empty array to store the XML data in that we are about to read.  Our Test-ErrorLog –Name parameter has its file extension changed to .XML.  As a matter of fact, all of our calls to the error log is now .XML instead of .CSV. 

The next big change is in the IF statement where we are testing to see if we are appending or not.  We added an ELSE statement.  This reads the objects in from the XML file and adds them to our array.  Remember, we cannot append directly to an XML file so we need to read the contents into memory before we can proceed.

Now, take a look at the changes in the CATCH block.  Very simple.  I choose not to use the –ErrorVariable parameter because I’ve noticed that we generally get more detail by using PowerShell’s built in capability.  The array $Error[0] is the most recent error received.  We simply add it to the array.

After we exit the ForEach loop, we commit the array to the XML file.  Once you run the code, use Import-CliXML to read the objects back into memory for processing.

The downside of XML is that you must read the current file in if you want to preserve it.  The upside is that you can store much more detailed information.

Well, that is it.  We generate basic log files in my PowerShell class, but I have a feeling that we will be changing that exercise to something a little more advance.




Comments

Jerris Heaton said…
Just curious... Do you prefer XML to JSON? If so, why? Seems JSON is easier to read when looking at it in raw format than XML. Is XML easier to manipulate in PowerShell vs. JSON?
Jerris,

Mostly a habit. I generally do not manually read my data files. Utilziing the ConvertTo-Json and ConvertFrom-Json cmdlets will let you utilize JSON.

Have a good evening,
Jason

Popular posts from this blog

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.

How to run GPResult on a remote client with PowerShell

In the past, to run the GPResult command, you would need to either physically visit this client, have the user do it, or use and RDP connection.  In all cases, this will disrupt the user.  First, you need PowerShell remoting enabled on the target machine.  You can do this via Group Policy . Open PowerShell and type this command. Invoke-Command –ScriptBlock {GPResult /r} –ComputerName <ComputerName> Replace <ComputerName> with the name of the target.  Remember, the target needs to be online and accessible to you.

Error icon when creating a GPO Preference drive map

You may not have an error at all.  Take a look at the drive mapping below. The red triangle is what threw us off.  It is not an error.  It is simply a color representation of the Replace option of the Action field in the properties of the drive mappings. Create action This give you a green triangle. The Create action creates a new mapped drive for users. Replace Action The Replace action gives you a red triangle.  This action will delete and recreate mapped drives for users. The net result of the Replace action is to overwrite all existing settings associated with the mapped drive. If the drive mapping does not exist, then the Replace action creates a new drive mapping. Update Action The Update action will have a yellow triangle. Update will modify settings of an existing mapped drive for users. This action differs from Replace in that it only updates settings defined within the preference item. All other settings remain as configured on the mapped drive. If the