AdvancedLogging.psm1

<#
.SYNOPSIS
    PowerShell Logging Module
.DESCRIPTION
    Provides a robust logging system that can be reused in various scripts, including writing to both log files and Windows Event Log.
    Supports log levels for filtering and can optionally output to the console.
.NOTES
    Version: 1.0.3
    Author: iwanttosleep
#>


#region Module Setup

# Define global variables for logging
$Global:LogName = "Application"
$Global:SourceName = "MyScripts"
$Global:CompanyName = $null
$Global:CompanyData = $null
$Global:LogFilePath = "C:\\MyCompany\\Monitoring"  # Default path, will be updated based on company data
$Global:LogFileName = "Log_" + (Get-Date -Format "yyyy-MM-dd_HH-mm-ss") + ".log"
$Global:FullLogPath = Join-Path -Path $LogFilePath -ChildPath $LogFileName
$Global:LogLevel = "INFO"  # Default log level

# Create an event log, if it doesn't already exist.
New-EventLog -LogName $Global:LogName -Source $Global:SourceName -ErrorAction SilentlyContinue

#endregion

#region Functions

# Function to set log level
function Set-LogLevel {
    param (
        [Parameter(Mandatory = $true)]
        [ValidateSet("INFO", "WARN", "ERROR", "DEBUG", "VERBOSE")]
        [string]$Level
    )

    $Global:LogLevel = $Level
}

# Function to write log messages with level filtering
function Write-Log {
    param (
        [Parameter(Mandatory = $true)]
        [string]$Message,

        [Parameter(Mandatory = $false)]
        [ValidateSet("INFO", "WARN", "ERROR", "DEBUG", "VERBOSE")]
        [string]$Level = "INFO",

        [Parameter(Mandatory = $false)]
        [switch]$PrintToConsole = $false
    )

    if (-not (Test-Path -Path $Global:LogFilePath)) {
        New-Item -ItemType Directory -Path $Global:LogFilePath | Out-Null
    }

    if ($Level -eq "DEBUG" -and $Global:LogLevel -ne "DEBUG") { return }
    if ($Level -eq "VERBOSE" -and $Global:LogLevel -notin @("DEBUG", "VERBOSE")) { return }

    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logEntry = "$timestamp [$Level] - $Message"

    if ($PrintToConsole) { Write-Output $logEntry }
    Add-Content -Path $Global:FullLogPath -Value $logEntry
}

# Function to log to Windows Event Log
function Write-EventLogEntry {
    param (
        [Parameter(Mandatory = $true)]
        [string]$Message,

        [Parameter(Mandatory = $false)]
        [int]$EventId = 1,

        [Parameter(Mandatory = $false)]
        [System.Diagnostics.EventLogEntryType]$EntryType = [System.Diagnostics.EventLogEntryType]::Information
    )

    if (-not (Get-EventLog -LogName $Global:LogName -Source $Global:SourceName -ErrorAction SilentlyContinue)) {
        New-EventLog -LogName $Global:LogName -Source $Global:SourceName -ErrorAction SilentlyContinue
    }

    Write-EventLog -LogName $Global:LogName -Source $Global:SourceName -EntryType $EntryType -EventId $EventId -Message $Message
    Write-Log -Message $Message -Level "EVENT"
}

# Get Company data by default, Domain name or tenant name
# Parse DSREG command
function Get-CompanyData {
    $DSREG = dsregcmd.exe /status
    $CompanyData = $DSREG | Select-String -Pattern "DeviceId", "DomainName", "TenantName", "AzureADJoined", "EnterpriseJoined", "DomainJoined"
    
    # Create a custom object to hold the properties
    $companyObject = [PSCustomObject]@{}

    # Parse and assign properties to the custom object
    $CompanyData | ForEach-Object {
        $data = $_ -split ":", 2
        $propertyName = $data[0].Trim()
        $propertyValue = $data[1].Trim()
        
        # Add the property to the custom object
        Add-Member -InputObject $companyObject -MemberType NoteProperty -Name $propertyName -Value $propertyValue
    }

    # Set the company name based on available data (DomainName or TenantName)
    if ($null -ne $companyObject.DomainName) {
        $Global:CompanyName = $companyObject.DomainName
    }
    elseif ($null -ne $companyObject.TenantName) {
        $Global:CompanyName = $companyObject.TenantName
    }

    # Update the log file path if CompanyName is available
    if ($null -ne $Global:CompanyName) {
        $Global:LogFilePath = "C:\\$($Global:CompanyName)\\Monitoring"
        $Global:FullLogPath = Join-Path -Path $Global:LogFilePath -ChildPath $Global:LogFileName
    }

    return $companyObject
}

Get-CompanyData
#endregion

# Export functions
Export-ModuleMember -Function Set-LogLevel, Write-Log, Write-EventLogEntry, Get-CompanyData