Monday 17 March 2014

SharePoint - Export to Excel and removing # and numbers from lookup and people columns

When a list is exported to Excel from SharePoint you may see entries for lookup columns and People like this

myentry;#32;anotherentry;#43

We can remove these by creating a column next to the column with these entries - say that the above is in column C1

Use this formula in the new column in D1:

=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(C1,"0",""),"1",""),"2",""),"3",""),"4",""),"5",""),"6",""),"7",""),"8",""),"9",""),";#;#","; "),";#","")

This will remove the #no bits. Copy this column and then paste it over the original column (C) as "Values". Then remove the column you used in the formula (D)

Thursday 13 March 2014

PowerShell - Write array of objects to a SQL table


This script srite array of objects to a SQL table. The input is via the pipeline, so usage could be

Get-Process | .\write-sqltable.ps1 -sqlserver SQLServer -dbname Mydatabase -dbtable Mytable

Note: the table MUST already exist with the same column names as the properties of the objects being passed to it. Use the -purgetable switch if you need to empty the table each time the script is run.


Script: write-sqltable.ps1

# Script to write array of objects, via Pipeline into a SQL table.
# Property names of objects being passed must match the column names in the destination table
# Returns select failedRowCount , SuccessRowCount , Errors 
# Params
# -sqlserver : Name or alias of SQL server instance
# -dbname : Name of the database
# -dbtable : Name of the database table
# -purgetable : [switch] Empty the table before writing back to it.

param ([string]$sqlServer = $(throw "SQL Server required"), [string]$dbName = $(throw "Database Required"),[string]$dbTable = $(throw "Database table Required"), [switch]$purgetable)
begin 
{
    $io = New-Object System.Collections.ArrayList;
}

process
{
    if ($_) {$io += $_}
}

end
{
    
    $conn = New-Object System.Data.SqlClient.SqlConnection("Data Source=$sqlServer;Initial Catalog=$dbName; Integrated Security=SSPI");
    $conn.Open();
    $cmd = $conn.CreateCommand();

    if ($purgetable){
        $cmd.CommandText = "DELETE from $dbtable"
        $cmd.ExecuteNonQuery() | out-null
        
    }
    if ($io -ne $null){
        $props = $io | select -First 1 | Get-Member -Membertype NoteProperty | foreach {$_.name}
        $successRowCount = 0
        $failedRowCount = 0
        $errors = @()
        foreach ($obj in $io)
        {
            $error.clear()
            $dbrowResult = $null
            $SQLInto = $null
            $SQLValues = $null
            $props | foreach {$SQLInto += $_ + ", "; $SQLValues += "'$($obj.$_)', "}
            $SQLInto = $SQLInto.trimEnd(", ")
            $SQLValues = $SQLValues.TrimEnd(", ")
            write-host "INSERT INTO $dbTable ($SQLInto) VALUES ($SQLValues)"
            $cmd.CommandText = "INSERT INTO $dbTable ($SQLInto) VALUES ($SQLValues)";
            try{$dbrowResult = $cmd.ExecuteNonQuery()}catch{}
            if ($dbrowResult -eq $null){
                $failedRowCount ++
                $errors += $error
                
            }
            else {
                $successRowCount ++
            }


        }
        
        $results = "" | select failedRowCount , SuccessRowCount , Errors 
        $results.failedRowCount = $failedRowCount
        $results.SuccessRowCount = $SuccessRowCount
        $flaterrors = ""
        $errors | Sort-Object -Unique | foreach {$results.Errors += ("{0}," -f $_)} | out-null; try{$results.Errors = ($results.Errors).TrimEnd(",")}catch{}
        $results
    }
    $conn.close();
}

Tuesday 11 March 2014

SharePoint 2007 \ 2010 - PowerShell script to get SharePoint audit information



This script outputs audit events as an array of objects, which can the be exported to csv using the | export-csv function:

.\get-spauditReport.ps1 -url <SiteCollection> -daysback 10 | export-csv <csv file>


It should work on SharePoint 2007 and 2010 - I haven't tested on 2013, but I think it should work.

The usage is in the comments at the start. Note that if there is heavy usage on the site collection, be mindful of the number of days the report should include, as memory may be an issue.


Script: get-spauditReport.ps1

# Script to output SharePoint audit information - can be exported to csv.
# Parameters:
# -url : URL of site collection
# -daysback : Number of days back from today that the audit information is to be collected from
# -startdate : As opposed to -daysback, use this as a start date for the audit report
# -enddate : Used with -startdate for the end date of the report
# -previousmonth : [switch] Previous full month for the report to use. Good if you want to run as a scheduled task every month
# -excludeusers : Can be an array of users that you don't want to appear on the report - i.e. monitoring accounts etc
# -excludeurls : excluded urls from the report - some system urls excluded by default, but will be overridden if used
# -includeRawevent : [switch] Included the raw event data from the SharePoitn audit
# -filterevent : Only returns events stated in the param
# -principle : If stated, only events for this account will be return.


param ($url, $daysback, $startdate, $enddate, [switch]$previousmonth, $excludeusers = ("SHAREPOINT\system"), $excludeurls = ("/Style Library/portal","/_catalogs","/_themes") , [switch]$includeRawEvent, $filterEvent, $principal)


[void][System.reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[void][System.reflection.Assembly]::LoadWithPartialName("System")

# Funcions

# Function: To create new object for results output
function New-AuditObj(){

    $auditobj = new-object PSObject
    $auditobj | add-member -type NoteProperty -name LoginName -Value "" 
    $auditobj | add-member -type NoteProperty -name DisplayName -Value "" 
    $auditobj | add-member -type NoteProperty -name Email -Value "" 
    $auditobj | add-member -type NoteProperty -name SPUserID -Value "" 
    $auditobj | add-member -type NoteProperty -name Event -Value "" 
    $auditobj | add-member -type NoteProperty -name Item -Value "" 
    $auditobj | add-member -type NoteProperty -name ItemType -Value "" 
    $auditobj | add-member -type NoteProperty -name Version -Value "" 
    $auditobj | add-member -type NoteProperty -name EventData -Value ""
    $auditobj | add-member -type NoteProperty -name EventDataRaw -Value ""     
    $auditobj | add-member -type NoteProperty -name AuditTime -Value "" 

    return $auditobj
}

# Function: Return Values based on Permission Level Mask
function get-PermissionLevelMask($maskno)
{
    switch ($maskno)
    {
        "0" {
            Return "EmptyMask"
        }       
        "1" {
            Return "ViewListItems"
        }       
        "2" {
            Return "AddListItems"
        }       
        "4" {
            Return "EditListItems"
        }       
        "8" {
            Return "DeleteListItems"
        }       
        "16" {
            Return "ApproveItems"
        }       
        "32" {
            Return "OpenItems"
        }       
        "64" {
            Return "ViewVersions"
        }       
        "128" {
            Return "DeleteVersions"
        }       
        "256" {
            Return "CancelCheckout"
        }       
        "512" {
            Return "ManagePersonalViews"
        }       
        "2048" {
            Return "ManageLists"
        }       
        "4096" {
            Return "ViewFormPages"
        }       
        "65536" {
            Return "Open"
        }       
        "131072" {
            Return "ViewPages"
        }       
        "262144" {
            Return "AddAndCustomizePages"
        }       
        "524288" {
            Return "ApplyThemeAndBorder"
        }       
        "1048576" {
            Return "ApplyStyleSheets"
        }       
        "2097152" {
            Return "ViewUsageData"
        }       
        "4194304" {
            Return "CreateSSCSite"
        }       
        "8388608" {
            Return "ManageSubwebs"
        }       
        "16777216" {
            Return "CreateGroups"
        }       
        "33554432" {
            Return "ManagePermissions"
        }       
        "67108864" {
            Return "BrowseDirectories"
        }       
        "134217728" {
            Return "BrowseUserInfo"
        }       
        "268435456" {
            Return "AddDelPrivateWebParts"
        }       
        "536870912" {
            Return "UpdatePersonalWebParts"
        }       
        "1073741824" {
            Return "ManageWeb"
        }       
        "68719476736" {   
            Return "UseClientIntegration "
        }
        "137438953472" {
            Return "UseRemoteAPIs"
        }       
        "274877906944" {
            Return "ManageAlerts"
        }       
        "549755813888" {
            Return "CreateAlerts"
        }       
        "1099511627776" {
            Return "EditMyUserInfo"
        }       
        "4611686018427387904" {
            Return "EnumeratePermissions"
        }       
        "9223372036854775807" {
            Return "FullMask"
        }       
   
   
   
    }

}

# Function: Return Values based on audit level mask
function get-auditMask($maskno){
    switch ($maskno)
        {
            "-1" {
                #Return "All types of events and actions."
                Return "All"
            }
            "0" {
                #Return "No events or actions."
                Return "None"
            }
            "1" {
                #Return "Check out of the object."
                Return "CheckOut"
            }
            "2" {
                #Return "Check in of the object."
                Return "CheckIn"
            }
            "4" {
                #Return "Viewing of the object by a user."
                Return "View"
            }
            "8" {
                #Return "Deletion of the object."
                Return "Delete"
            }
            "16" {
                #Return "Update of the object."
                Return "Update"
            }
            "32" {
                #Return "Change of a profile."
                Return "ProfileChange"
            }
            "64" {
                #Return "Deletion of one of the object's child objects."
                Return "ChildDelete"
            }
            "128" {
                #Return "Change of the object's schema."
                Return "SchemaChange"
            }
            "256" {
                #Return "Change in a security configuration for the object."
                Return "SecurityChange"
            }
            "512" {
                #Return "Reversal of the deletion of the object."
                Return "Undelete"
            }
            "1024" {
                #Return "Use of the object in a workflow task."
                Return "Workflow"
            }
            "2048" {
                #Return "Copying the object."
                Return "Copy"
            }
            "4096" {
                #Return "Move of the object."
                Return "Move"
            }
            "8192" {
                #Return "Search of the object."
                Return "Search"
            }
                                                                                                                                                                                              
       
       
        }
       

}

## Start a loop that will run until both $sd (Start Date) and $ed (End Date) variables are assigned values
while (-not ($sd -and $ed))
{
    ## If the -daysback parameter was specified, set $ed to current timestamp and $sd to the specified number of days back
    if ($daysback)
    {
        ## The ToShortDateString() method is used to set the time value in the DateTime object to 00:00:00 (otherwise it will match current)
        $sd = (Get-Date (Get-Date).ToShortDateString()).AddDays(-$daysback);
        $ed = Get-Date;
       
        ## Stop processing the loop as the required values have been assigned
        break;
    }
   
    if ($previousmonth)
    {
        # get previous month days
        $date = get-date
        $numdays = $date.Day
        $ed = $date.AddDays(-$numdays)
        $numdays = $ed.Day
        $sd = $ed.AddDays( -$numdays + 1)
        $sd = ((($sd.AddHours(0-$sd.hour)).AddMinutes(0-$sd.Minute)).AddSeconds(0-$sd.Second)).AddMilliseconds(0-$sd.millisecond)
        $ed = $ed.AddDays(1)
        $ed = ((($ed.AddHours(0-$ed.hour)).AddMinutes(0-$ed.Minute)).AddSeconds(0-$ed.Second)).AddMilliseconds(0-$ed.millisecond)
        ## Stop processing the loop as the required values have been assigned
        break;
    }
   
    ## If the -startdate parameter was specified, use it create a DateTime object and assign it to $sd variable
    if ($startdate)
    {
        $sd = Get-Date ($startdate);
    }
   
    ## As start date was not specified, set $sd to the earliest date possible
    else
    {
        $sd = [DateTime]::MinValue;
    }

    ## If the -enddate parameter was specified, use it create a DateTime object and assign it to $ed variable
    if ($enddate)
    {
        $ed = Get-Date ($enddate);
    }
   
    ## As end date was not specified, set $ed to today
    else
    {
        $ed = Get-Date;
    }
}

# Set type of start date and end date
$sd = Get-Date $sd
$ed = Get-Date $ed

# Get Site object
$site = New-Object Microsoft.SharePoint.SPSite($url)

# Get List of site users
$SPSiteUsers = $site.RootWeb.SiteUsers
# Get Site User Ids of excluded users (as defined in parameter)
$ExcludeUserIds = $SPSiteUsers | where-Object {$excludeusers -contains $_.LoginName} | foreach {$_.ID}
# Create gerneal query object
$query = New-Object Microsoft.SharePoint.SPAuditQuery($site)
$query.SetRangeStart($sd)
$query.SetRangeEnd($ed)

# Filter our events if defined in parametes
if ($filterEvent){
    Write-Host "  - Filtering Events:"
    $filterEvent | ForEach-Object {
        Write-Host "    - $_"
        $query.AddEventRestriction($_)
    }
}

# Get Prinicpal ID (from parameter) and set query to use it
if ($principal){
    $id = ($SPSiteUsers | Where-Object {$_.loginname -ilike "*$principal*"}).id
    if ($id){
        $query.RestrictToUser($id)
    }
    else{
        Write-Host "   - $principal does not exist on the site."
    }
}
# Get Audit Entries, excluding urls (as specified in parameters)
$auditEntries = $site.Audit.GetEntries($query) | Where-Object {$ExcludeUserIds -notcontains $_.userID } | ForEach-Object {$found = $false; if ($excludeurls){foreach ($exurl in $excludeurls){if($_.Doclocation -ilike "*$exurl*"){$found = $true}}; if ($found -eq $false){$_}}}
# reset Audit counter (for progress bar)
$auditcount = 0;

# Preloading objects from SharePoint - for efficency

# Get SecGroupCreate audit entries
$groupquery = New-Object Microsoft.SharePoint.SPAuditQuery($site)
$groupquery.AddEventRestriction("SecGroupCreate")
$SecGroupCreateEntries = $site.Audit.GetEntries($groupquery)

# Get SecRoleDefCreate and SecRoleDefModify audit entries
$rolequery = New-Object Microsoft.SharePoint.SPAuditQuery($site)
$rolequery.AddEventRestriction("SecRoleDefCreate")
$rolequery.AddEventRestriction("SecRoleDefModify")               
$SecRoleEntries = $site.Audit.GetEntries($rolequery)

# Loop through all audit entries, so we can process them
foreach ($AuditItem in $auditEntries){
    # Reset Principal variable
    $principal = $null
    # Increment counter
    $auditcount ++;
    # Progress bar
    if ($auditEntries.Count -gt 0){
        Write-Progress -activity "Processing Audit Logs for $url" -status "Processed: $auditCount of $($auditEntries.Count)" -PercentComplete (($auditcount / $auditEntries.Count)  * 100)
    }
    # Create new Audit output object
    $AuditObj = New-AuditObj
   
    # Get User Info
    try{
        $user = $SPSiteUsers.GetByID($audititem.UserId)
        $auditobj.LoginName = $user.LoginName
        $auditobj.DisplayName = $user.Name
        $auditobj.Email = $user.Email
        $auditobj.SPUserID = $user.ID
    }
    catch{
        $auditobj.LoginName = "User Removed"
        $auditobj.SPUserID = $audititem.UserId
    }
   
    # Get Item Info

    $auditobj.Event = $auditItem.Event
    $auditobj.Item = $auditItem.DocLocation
    $auditobj.ItemType = $auditItem.ItemType
    $auditobj.AuditTime = $auditItem.Occurred
    $auditobj.EventDataRaw = $AuditItem.EventData   
   
    if($auditobj.Item -ilike "*agenda.doc*")
    {
        Write-Host "Here"
    }
   
    if ((($auditItem.DocLocation).EndsWith(".aspx"))){
        $auditobj.ItemType = "Page"
    }
    # Calculate version info
    if ($AuditItem.EventData -eq ""){
        $auditobj.Version = "N/A"
    }
    if ($AuditItem.EventData -ilike "*<allversions/>*"){
        $auditobj.Version = "All"
    }   
    try {
        [xml]$eventData = "<root>$($AuditItem.EventData)</root>"
        if ($eventData.root.Version.Major -ne $null -and $eventData.Version.root.Minor -ne ""){
            if ($eventData.root.Version.Major -eq "0" -and $eventData.Version.root.Minor -eq "-1")
            {
                $auditobj.Version = "N/A"
            }
            else{
                $auditobj.Version = $eventData.root.Version.Major + "." + $eventData.root.Version.Minor
            }
        }
       
    }
    catch{}

    # Reset general EventData variable
    Remove-Variable eventData
    # Switch based on event type
    switch ($auditItem.Event)
        {
            "AuditMaskChange" {
                # Get mask from EventData
                $permissionMask = ([xml]($AuditItem.EventData)).NewAuditMask
                $auditobj.EventData = "Auditing Events: "
                # Go through each mask and bit and them - evaluation passed to "Get-AuditMask" function for actual values
                8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1 | foreach {if (($permissionMask -band $_) -gt 0){$auditobj.EventData += $(get-auditMask ($permissionMask -band $_)) + " "}}

            }
            "Move" {
                [xml]$eventData = $AuditItem.EventData
                $auditobj.EventData = "Moved to: {0}" -f $EventData.NewName
            }

            "ChildMove" {
                [xml]$eventData = $AuditItem.EventData
                $auditobj.EventData = "Moved to: {0}" -f $EventData.RelatedItem.NewName
            }            
            "Delete" {
           
                if ($($AuditItem.EventData) -ilike "*<Recycle>1<Recycle>*")           
                    {$auditobj.EventData = "Sent to the recycle bin"}
                if ($($AuditItem.EventData) -ilike "*<Recycle>0<Recycle>*")           
                    {$auditobj.EventData = "Permantently Deleted"}              
                   
                }    
            "UnDelete" {
                $auditobj.EventData = "Restored from the recycle bin"
                }                         
            "ChildDelete" {
                $auditobj.EventData = "Deleted {0}" -f $($eventData.RelatedItem.Location)
            }
            "EventsDeleted" {
                [xml]$eventData = $AuditItem.EventData              
                $auditobj.EventData = "{0} audit rows deleted before {1}" -f $eventdata.DeleteEntriesInfo.Rows, $(get-date ($eventdata.DeleteEntriesInfo.EndDate)).TosTring()
            }
            "View" {
                $auditobj.EventData = ""
            }
            "Search" {
                $eventData = $AuditItem.EventData
                $query = ($eventData.split(";")[0]).replace("query=","")
                $context = ($eventData.split(";")[1]).replace("constraint=' ","").replace("'","").replace("site:","").replace('"',"")
                $auditobj.EventData = "Searched for {0} in {1}" -f $query, $context

            }
                                        
            "SecGroupMemberAdd" {
                [xml]$eventdata = "<root>$($AuditItem.EventData)</root>"
                $GroupID = $eventData.root.groupid
                if ($GroupID -gt 0){
                    try {$GroupName = (($site.RootWeb.SiteGroups).GetByID($eventData.root.groupid)).Name}catch{}
                    if (!$groupName){
                        $SecGroupCreateEntries  | Where-Object {$_.EventData -ilike "*<groupid>$GroupID</groupid>*"} | Select -First 1 | foreach {[xml]$eventdata = ("<root>$($_.EventData)</root>").replace("&","&amp;"); $GroupName =  $eventData.root.title}

                    }
                    try {$principal = $SPSiteUsers.GetById($eventdata.root.user)}catch{}
                    if ($principal -ne $null){
                        $userinfo = "{0} ({1})" -f $principal.loginname, $principal.email
                    }
                    else
                    {
                        $userinfo = $eventdata.root.username
                    }
                    $auditobj.EventData = "Added {0} to Group: {1}" -f $userinfo, $GroupName
                }
            }                
           
            "SecGroupMemberDel" {
                [xml]$eventdata = "<root>$($AuditItem.EventData)</root>"
                try {$principal = $SPSiteUsers.GetById($eventdata.root.user)}catch{}
                if ($principal -ne $null){
                    $userinfo = "{0} ({1})" -f $principal.loginname, $principal.email
                }
                else{
                    $userinfo = "UserID: $($eventdata.root.user)"
                }  
                try {$GroupName = (($site.RootWeb.SiteGroups).GetByID($eventData.root.groupid)).Name}catch{}
                if (!$groupName){
                    $SecGroupCreateEntries  | Where-Object {$_.EventData -ilike "*<groupid>$GroupID</groupid>*"} | Select -First 1 | foreach {[xml]$eventdata = ("<root>$($_.EventData)</root>").replace("&","&amp;"); $GroupName =  $eventData.root.title}

                    }                           
                $auditobj.EventData = "Removed {0} from Group: {1}" -f $userinfo, $GroupName
            }               

            "SecGroupCreate" {
                [xml]$eventdata = ("<root>$($AuditItem.EventData)</root>").replace("&","&amp;")
                $auditobj.EventData = "Group Created: {0}" -f $eventData.root.title
            }             

            "SecGroupDelete" {
                [xml]$eventdata = "<root>$($AuditItem.EventData)</root>"
                $SecGroupCreateEntries | Where-Object {$_.EventData -ilike "*<groupid>$($eventData.root.groupid)</groupid>*"} | Select -First 1 | foreach {[xml]$eventdata = ("<root>$($_.EventData)</root>").replace("&","&amp;"); $auditobj.EventData = "Group Deleted: {0}" -f $eventData.root.title}
            }  
           
            "SecRoleBindUpdate" {
                [xml]$eventdata = "<root>$($AuditItem.EventData)</root>"
                try {$principal = $SPSiteUsers.GetById($eventdata.root.principalid)}catch{}
                if ($principal){
                    $principalInfo = "{0} ({1})" -f $principal.loginname, $principal.email
                }
                else{
                    # The Principle may be a group
                    try{$principal = (($site.RootWeb.SiteGroups).GetById($eventData.root.principalid)).Name}catch{}
                     $principalInfo = "$principal"
                }

                if ($eventdata.root.roleid -eq -1){
                    $permission = "All"
                }
                elseif ($eventdata.root.roleid -eq "0")
                {
                    $permission = "None"
                }
                else{
                    $permission = ($site.RootWeb.RoleDefinitions | Where-Object {$_.id -eq $eventData.root.roleid}).name
                }
                $operation = ($eventdata.root.operation).replace("ensure ","")
                $auditobj.EventData = "'{0}' permission {1} : {2}" -f $permission, $operation, $principalInfo
            }
            "SecRoleBindInherit" {
                [xml]$eventdata = "<root>$($AuditItem.EventData)</root>"
                $auditobj.EventData = "Item Url: {0}" -f $($eventdata.root.url)
            }                    
            "SecRoleBindBreakInherit" {
                [xml]$eventdata = "<root>$($AuditItem.EventData)</root>"
                $auditobj.EventData = "Item Url: {0}" -f $($eventdata.root.url)
            }
            "SecRoleDefCreate" {
                [xml]$eventdata = "<root>$($AuditItem.EventData)</root>"
                $permissionMask = $($eventdata.root.perm)
                $auditobj.EventData = "{0}: " -f $($eventdata.root.name)
                1,2,4,8,16,32,64,128,256,512,2048,4096,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,68719476736,137438953472,274877906944,549755813888,1099511627776,4611686018427387904,9223372036854775807`
                 | foreach {if (($permissionMask -band $_) -gt 0){$auditobj.EventData += $(get-PermissionLevelMask ($permissionMask -band $_)) + " "}}
            }            
            "SecRoleDefModify" {
                [xml]$eventdata = "<root>$($AuditItem.EventData)</root>"
                $permissionMask = $($eventdata.root.perm)
                $auditobj.EventData = "{0}: " -f $($eventdata.root.name)
                1,2,4,8,16,32,64,128,256,512,2048,4096,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,68719476736,137438953472,274877906944,549755813888,1099511627776,4611686018427387904,9223372036854775807`
                 | foreach {if (($permissionMask -band $_) -gt 0){$auditobj.EventData += $(get-PermissionLevelMask ($permissionMask -band $_)) + " "}}
            }   
            "SecRoleDefDelete" {
                [xml]$eventdata = $AuditItem.EventData
                $SecRoleEntries| Where-Object {$_.EventData -ilike "*<id>$($eventData.id)</id>*"} | Select -First 1 | foreach {[xml]$eventdata = "<root>$($_.EventData)</root>"; $auditobj.EventData = "Permission Level Deleted: {0}" -f $eventData.root.name}
            }                                                                                                                                                                                       
            default {}
        }


    if (-not $includeRawEvent){
        $auditobj | Select-Object * -exclude EventDataRaw
    }
    else{
        $auditobj
    }

}

# End Script