Discover powerful PowerShell programs and scripts to automate tasks, manage systems, and enhance productivity. Learn to create, customize, and implement efficient PowerShell solutions for Windows administration, network management, and more. Explore expert tips, best practices, and real-world examples to master PowerShell programming and streamline your IT operations.

Folder Permission Analyzer Tool

<#
.SYNOPSIS
Folder Permission Analyzer Tool

.DESCRIPTION
This script analyzes and audits folder permissions on Windows systems, providing
insights into access rights, inheritance, and potential security issues.

.NOTES
File Name      : FolderPermissionAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, administrator rights
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\FolderPermissionAnalyzer.ps1
#>

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\Folder_Permission_Analysis_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
$global:targetPath = ""

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Folder Permission Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "Current Target Path: $global:targetPath"
    Write-Host "1. Set Target Folder Path"
    Write-Host "2. Analyze Folder Permissions"
    Write-Host "3. Check for Inherited Permissions"
    Write-Host "4. Identify Unique Permissions"
    Write-Host "5. Check for 'Everyone' Permissions"
    Write-Host "6. Analyze Nested Folder Permissions"
    Write-Host "7. Find Folders with Explicit Permissions"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Sets the target folder path for analysis.
#>
function Set-TargetFolderPath {
    $path = Read-Host "Enter the full path of the target folder"
    if (Test-Path -Path $path -PathType Container) {
        $global:targetPath = $path
        Write-Host "Target folder path set to: $global:targetPath" -ForegroundColor Green
    } else {
        Write-Host "Invalid path or folder does not exist." -ForegroundColor Red
    }
}

<#
.SYNOPSIS
Analyzes folder permissions.

.OUTPUTS
Array of PSObjects containing folder permission details.
#>
function Analyze-FolderPermissions {
    Write-Host "`nAnalyzing Folder Permissions..." -ForegroundColor Yellow
    if ([string]::IsNullOrWhiteSpace($global:targetPath)) {
        Write-Host "Target folder path is not set. Please set it first." -ForegroundColor Red
        return $null
    }

    $acl = Get-Acl -Path $global:targetPath
    $results = @()
    foreach ($ace in $acl.Access) {
        $results += [PSCustomObject]@{
            FolderName = Split-Path $global:targetPath -Leaf
            IdentityReference = $ace.IdentityReference
            AccessControlType = $ace.AccessControlType
            FileSystemRights = $ace.FileSystemRights
            IsInherited = $ace.IsInherited
            InheritanceFlags = $ace.InheritanceFlags
            PropagationFlags = $ace.PropagationFlags
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks for inherited permissions.

.OUTPUTS
Array of PSObjects containing inherited permission details.
#>
function Check-InheritedPermissions {
    Write-Host "`nChecking for Inherited Permissions..." -ForegroundColor Yellow
    if ([string]::IsNullOrWhiteSpace($global:targetPath)) {
        Write-Host "Target folder path is not set. Please set it first." -ForegroundColor Red
        return $null
    }

    $acl = Get-Acl -Path $global:targetPath
    $results = @()
    foreach ($ace in $acl.Access | Where-Object { $_.IsInherited -eq $true }) {
        $results += [PSCustomObject]@{
            FolderName = Split-Path $global:targetPath -Leaf
            IdentityReference = $ace.IdentityReference
            AccessControlType = $ace.AccessControlType
            FileSystemRights = $ace.FileSystemRights
            InheritanceFlags = $ace.InheritanceFlags
            PropagationFlags = $ace.PropagationFlags
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Identifies unique permissions.

.OUTPUTS
Array of PSObjects containing unique permission details.
#>
function Identify-UniquePermissions {
    Write-Host "`nIdentifying Unique Permissions..." -ForegroundColor Yellow
    if ([string]::IsNullOrWhiteSpace($global:targetPath)) {
        Write-Host "Target folder path is not set. Please set it first." -ForegroundColor Red
        return $null
    }

    $acl = Get-Acl -Path $global:targetPath
    $results = @()
    foreach ($ace in $acl.Access | Where-Object { $_.IsInherited -eq $false }) {
        $results += [PSCustomObject]@{
            FolderName = Split-Path $global:targetPath -Leaf
            IdentityReference = $ace.IdentityReference
            AccessControlType = $ace.AccessControlType
            FileSystemRights = $ace.FileSystemRights
            InheritanceFlags = $ace.InheritanceFlags
            PropagationFlags = $ace.PropagationFlags
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks for 'Everyone' permissions.

.OUTPUTS
Array of PSObjects containing 'Everyone' permission details.
#>
function Check-EveryonePermissions {
    Write-Host "`nChecking for 'Everyone' Permissions..." -ForegroundColor Yellow
    if ([string]::IsNullOrWhiteSpace($global:targetPath)) {
        Write-Host "Target folder path is not set. Please set it first." -ForegroundColor Red
        return $null
    }

    $acl = Get-Acl -Path $global:targetPath
    $results = @()
    foreach ($ace in $acl.Access | Where-Object { $_.IdentityReference -eq "Everyone" -or $_.IdentityReference -eq "NT AUTHORITY\Authenticated Users" }) {
        $results += [PSCustomObject]@{
            FolderName = Split-Path $global:targetPath -Leaf
            IdentityReference = $ace.IdentityReference
            AccessControlType = $ace.AccessControlType
            FileSystemRights = $ace.FileSystemRights
            IsInherited = $ace.IsInherited
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes nested folder permissions.

.OUTPUTS
Array of PSObjects containing nested folder permission details.
#>
function Analyze-NestedFolderPermissions {
    Write-Host "`nAnalyzing Nested Folder Permissions..." -ForegroundColor Yellow
    if ([string]::IsNullOrWhiteSpace($global:targetPath)) {
        Write-Host "Target folder path is not set. Please set it first." -ForegroundColor Red
        return $null
    }

    $results = @()
    $folders = Get-ChildItem -Path $global:targetPath -Directory -Recurse -Depth 2
    foreach ($folder in $folders) {
        $acl = Get-Acl -Path $folder.FullName
        foreach ($ace in $acl.Access) {
            $results += [PSCustomObject]@{
                FolderName = $folder.Name
                FullPath = $folder.FullName
                IdentityReference = $ace.IdentityReference
                AccessControlType = $ace.AccessControlType
                FileSystemRights = $ace.FileSystemRights
                IsInherited = $ace.IsInherited
            }
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Finds folders with explicit permissions.

.OUTPUTS
Array of PSObjects containing folders with explicit permissions.
#>
function Find-FoldersWithExplicitPermissions {
    Write-Host "`nFinding Folders with Explicit Permissions..." -ForegroundColor Yellow
    if ([string]::IsNullOrWhiteSpace($global:targetPath)) {
        Write-Host "Target folder path is not set. Please set it first." -ForegroundColor Red
        return $null
    }

    $results = @()
    $folders = Get-ChildItem -Path $global:targetPath -Directory -Recurse
    foreach ($folder in $folders) {
        $acl = Get-Acl -Path $folder.FullName
        if ($acl.Access | Where-Object { $_.IsInherited -eq $false }) {
            $results += [PSCustomObject]@{
                FolderName = $folder.Name
                FullPath = $folder.FullName
                ExplicitPermissionsCount = ($acl.Access | Where-Object { $_.IsInherited -eq $false }).Count
            }
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Folder Permission Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
    </style>
</head>
<body>
    <h1>Folder Permission Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>
    <p>Target Folder: $global:targetPath</p>

    <h2>Folder Permissions</h2>
    $($AllResults.FolderPermissions | ConvertTo-Html -Fragment)

    <h2>Inherited Permissions</h2>
    $($AllResults.InheritedPermissions | ConvertTo-Html -Fragment)

    <h2>Unique Permissions</h2>
    $($AllResults.UniquePermissions | ConvertTo-Html -Fragment)

    <h2>'Everyone' Permissions</h2>
    $($AllResults.EveryonePermissions | ConvertTo-Html -Fragment)

    <h2>Nested Folder Permissions</h2>
    $($AllResults.NestedPermissions | ConvertTo-Html -Fragment)

    <h2>Folders with Explicit Permissions</h2>
    $($AllResults.ExplicitPermissions | ConvertTo-Html -Fragment)
</body>
</html>
"@

    $reportContent | Out-File -FilePath $global:reportPath
    Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green
}

# Main program loop
$allResults = @{}

do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-9)"

    switch ($choice) {
        "1" { Set-TargetFolderPath }
        "2" { $allResults.FolderPermissions = Analyze-FolderPermissions }
        "3" { $allResults.InheritedPermissions = Check-InheritedPermissions }
        "4" { $allResults.UniquePermissions = Identify-UniquePermissions }
        "5" { $allResults.EveryonePermissions = Check-EveryonePermissions }
        "6" { $allResults.NestedPermissions = Analyze-NestedFolderPermissions }
        "7" { $allResults.ExplicitPermissions = Find-FoldersWithExplicitPermissions }
        "8" { Generate-HTMLReport -AllResults $allResults }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "9") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "9")

This Folder Permission Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of folder permissions:
    • Analysis of folder permissions
    • Check for inherited permissions
    • Identification of unique permissions
    • Check for ‘Everyone’ permissions
    • Analysis of nested folder permissions
    • Finding folders with explicit permissions
  3. Ability to set a target folder path for analysis.
  4. Comprehensive error handling for each analysis function.
  5. A function to generate an HTML report of all collected data.

Key features:

  • Detailed analysis of folder permissions, including access rights and inheritance
  • Identification of inherited vs. unique permissions
  • Detection of potentially risky ‘Everyone’ permissions
  • Analysis of permissions on nested folders
  • Identification of folders with explicit (non-inherited) permissions
  • Comprehensive HTML report generation

This tool is particularly useful for:

  • System administrators managing file system permissions
  • Security professionals auditing folder access rights
  • IT professionals troubleshooting permission-related issues
  • Compliance officers ensuring proper file system security

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to access and read folder permissions
  3. Be cautious when analyzing large directory structures, as it may take time for nested folder analysis

This script provides a comprehensive overview of folder permissions, making it easier to audit and maintain proper access controls, identify potential security issues, and ensure the correct configuration of folder permissions across Windows systems.

Workgroup Computer Audit Toolkit

<#
.SYNOPSIS
Workgroup Computer Audit Toolkit

.DESCRIPTION
This script performs a comprehensive audit of a Windows computer that is not part of a domain.
It checks various system settings, security configurations, and local information.

.NOTES
File Name      : WorkgroupComputerAuditToolkit.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, administrator rights on the local machine
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\WorkgroupComputerAuditToolkit.ps1
#>

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\Workgroup_Computer_Audit_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"

function Show-Menu {
    Clear-Host
    Write-Host "=== Workgroup Computer Audit Toolkit ===" -ForegroundColor Cyan
    Write-Host "1. System Information"
    Write-Host "2. Local User Accounts"
    Write-Host "3. Installed Software"
    Write-Host "4. Windows Update Status"
    Write-Host "5. Security Settings"
    Write-Host "6. Network Configuration"
    Write-Host "7. Shared Folders"
    Write-Host "8. Scheduled Tasks"
    Write-Host "9. Services Analysis"
    Write-Host "10. Generate Comprehensive HTML Report"
    Write-Host "11. Exit"
}

function Get-SystemInformation {
    Write-Host "`nGathering System Information..." -ForegroundColor Yellow
    $os = Get-WmiObject Win32_OperatingSystem
    $cs = Get-WmiObject Win32_ComputerSystem
    $bios = Get-WmiObject Win32_BIOS

    $result = [PSCustomObject]@{
        ComputerName = $env:COMPUTERNAME
        OSName = $os.Caption
        OSVersion = $os.Version
        OSArchitecture = $os.OSArchitecture
        Manufacturer = $cs.Manufacturer
        Model = $cs.Model
        BIOSVersion = $bios.SMBIOSBIOSVersion
        LastBootUpTime = $os.ConvertToDateTime($os.LastBootUpTime)
        InstallDate = $os.ConvertToDateTime($os.InstallDate)
        WorkgroupName = $cs.Workgroup
    }

    $result | Format-List
    return $result
}

function Get-LocalUserAccounts {
    Write-Host "`nGathering Local User Account Information..." -ForegroundColor Yellow
    $users = Get-WmiObject Win32_UserAccount -Filter "LocalAccount=True"
    $results = @()

    foreach ($user in $users) {
        $results += [PSCustomObject]@{
            Username = $user.Name
            FullName = $user.FullName
            Disabled = $user.Disabled
            PasswordRequired = $user.PasswordRequired
            PasswordChangeable = $user.PasswordChangeable
            PasswordExpires = $user.PasswordExpires
        }
    }

    $results | Format-Table -AutoSize
    return $results
}

function Get-InstalledSoftware {
    Write-Host "`nGathering Installed Software Information..." -ForegroundColor Yellow
    $software = Get-WmiObject Win32_Product | Select-Object Name, Version, Vendor, InstallDate
    $software | Format-Table -AutoSize
    return $software
}

function Get-WindowsUpdateStatus {
    Write-Host "`nChecking Windows Update Status..." -ForegroundColor Yellow
    $updateSession = New-Object -ComObject Microsoft.Update.Session
    $updateSearcher = $updateSession.CreateUpdateSearcher()
    $pendingUpdates = $updateSearcher.Search("IsInstalled=0")

    $result = [PSCustomObject]@{
        PendingUpdatesCount = $pendingUpdates.Updates.Count
        LastUpdateDate = (Get-HotFix | Sort-Object -Property InstalledOn -Descending | Select-Object -First 1).InstalledOn
    }

    $result | Format-List
    return $result
}

function Get-SecuritySettings {
    Write-Host "`nGathering Security Settings..." -ForegroundColor Yellow
    $firewallStatus = Get-NetFirewallProfile | Select-Object Name, Enabled
    $avProduct = Get-WmiObject -Namespace root\SecurityCenter2 -Class AntiVirusProduct
    $uac = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA"

    $result = [PSCustomObject]@{
        FirewallStatus = $firewallStatus
        AntiVirusProduct = $avProduct.displayName
        UACEnabled = $uac.EnableLUA -eq 1
    }

    $result | Format-List
    return $result
}

function Get-NetworkConfiguration {
    Write-Host "`nGathering Network Configuration..." -ForegroundColor Yellow
    $adapters = Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object { $_.IPEnabled -eq $true }
    $results = @()

    foreach ($adapter in $adapters) {
        $results += [PSCustomObject]@{
            AdapterName = $adapter.Description
            IPAddress = $adapter.IPAddress -join ", "
            SubnetMask = $adapter.IPSubnet -join ", "
            DefaultGateway = $adapter.DefaultIPGateway -join ", "
            DNSServers = $adapter.DNSServerSearchOrder -join ", "
            MACAddress = $adapter.MACAddress
        }
    }

    $results | Format-Table -AutoSize
    return $results
}

function Get-SharedFolders {
    Write-Host "`nGathering Shared Folder Information..." -ForegroundColor Yellow
    $shares = Get-WmiObject Win32_Share
    $results = @()

    foreach ($share in $shares) {
        $results += [PSCustomObject]@{
            Name = $share.Name
            Path = $share.Path
            Description = $share.Description
            Type = switch ($share.Type) {
                0 {"Disk Drive"}
                1 {"Print Queue"}
                2 {"Device"}
                3 {"IPC"}
                2147483648 {"Disk Drive Admin"}
                2147483649 {"Print Queue Admin"}
                2147483650 {"Device Admin"}
                2147483651 {"IPC Admin"}
            }
        }
    }

    $results | Format-Table -AutoSize
    return $results
}

function Get-ScheduledTasks {
    Write-Host "`nGathering Scheduled Task Information..." -ForegroundColor Yellow
    $tasks = Get-ScheduledTask | Where-Object {$_.State -ne "Disabled"}
    $results = @()

    foreach ($task in $tasks) {
        $results += [PSCustomObject]@{
            TaskName = $task.TaskName
            State = $task.State
            LastRunTime = $task.LastRunTime
            NextRunTime = $task.NextRunTime
            Author = $task.Author
        }
    }

    $results | Format-Table -AutoSize
    return $results
}

function Get-ServicesAnalysis {
    Write-Host "`nAnalyzing Services..." -ForegroundColor Yellow
    $services = Get-WmiObject Win32_Service
    $results = @()

    foreach ($service in $services) {
        $results += [PSCustomObject]@{
            Name = $service.Name
            DisplayName = $service.DisplayName
            StartMode = $service.StartMode
            State = $service.State
            StartName = $service.StartName
        }
    }

    $results | Format-Table -AutoSize
    return $results
}

function Generate-HTMLReport {
    param([hashtable]$AllResults)

    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Workgroup Computer Audit Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .warning { color: orange; }
        .critical { color: red; }
    </style>
</head>
<body>
    <h1>Workgroup Computer Audit Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>System Information</h2>
    $($AllResults.SystemInfo | ConvertTo-Html -Fragment)

    <h2>Local User Accounts</h2>
    $($AllResults.LocalUsers | ConvertTo-Html -Fragment)

    <h2>Installed Software</h2>
    $($AllResults.InstalledSoftware | ConvertTo-Html -Fragment)

    <h2>Windows Update Status</h2>
    $($AllResults.WindowsUpdateStatus | ConvertTo-Html -Fragment)

    <h2>Security Settings</h2>
    $($AllResults.SecuritySettings | ConvertTo-Html -Fragment)

    <h2>Network Configuration</h2>
    $($AllResults.NetworkConfig | ConvertTo-Html -Fragment)

    <h2>Shared Folders</h2>
    $($AllResults.SharedFolders | ConvertTo-Html -Fragment)

    <h2>Scheduled Tasks</h2>
    $($AllResults.ScheduledTasks | ConvertTo-Html -Fragment)

    <h2>Services Analysis</h2>
    $($AllResults.ServicesAnalysis | ConvertTo-Html -Fragment)
</body>
</html>
"@

    $reportContent | Out-File -FilePath $global:reportPath
    Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green
}

# Main program loop
$allResults = @{}

do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-11)"

    switch ($choice) {
        "1" { $allResults.SystemInfo = Get-SystemInformation }
        "2" { $allResults.LocalUsers = Get-LocalUserAccounts }
        "3" { $allResults.InstalledSoftware = Get-InstalledSoftware }
        "4" { $allResults.WindowsUpdateStatus = Get-WindowsUpdateStatus }
        "5" { $allResults.SecuritySettings = Get-SecuritySettings }
        "6" { $allResults.NetworkConfig = Get-NetworkConfiguration }
        "7" { $allResults.SharedFolders = Get-SharedFolders }
        "8" { $allResults.ScheduledTasks = Get-ScheduledTasks }
        "9" { $allResults.ServicesAnalysis = Get-ServicesAnalysis }
        "10" { Generate-HTMLReport -AllResults $allResults }
        "11" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "11") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "11")

This Workgroup Computer Audit Toolkit includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to gather various aspects of the local Windows computer:
    • System Information
    • Local User Accounts
    • Installed Software
    • Windows Update Status
    • Security Settings
    • Network Configuration
    • Shared Folders
    • Scheduled Tasks
    • Services Analysis
  3. HTML report generation for easy sharing and viewing of results.

Key features:

  • Comprehensive system information gathering
  • Local user account analysis
  • Software inventory
  • Windows Update status check
  • Basic security settings review (firewall, antivirus, UAC)
  • Network configuration details
  • Shared folder enumeration
  • Active scheduled tasks listing
  • Services analysis

This tool is particularly useful for:

  • IT administrators performing audits on standalone or workgroup computers
  • Security professionals assessing the configuration of non-domain Windows machines
  • Help desk personnel gathering system information for troubleshooting
  • Anyone needing to quickly collect comprehensive information about a Windows computer not joined to a domain

To use this script effectively:

  1. Run PowerShell as an administrator on the Windows computer you want to audit
  2. Ensure you have the necessary permissions to query system information
  3. Review the generated HTML report for a comprehensive overview of the computer’s configuration

This script provides a thorough audit of a workgroup Windows computer, helping to identify potential issues, misconfigurations, or security concerns. It’s designed to be run locally on the machine being audited, making it suitable for situations where centralized management tools are not available.

LDAP and LDAPS Check Toolkit

<#
.SYNOPSIS
LDAP and LDAPS Check Toolkit

.DESCRIPTION
This script provides comprehensive checks and tests for LDAP and LDAPS configurations,
including connectivity, security, and certificate validation.

.NOTES
File Name      : LDAPCheckToolkit.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, appropriate permissions
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\LDAPCheckToolkit.ps1
#>

# Import required modules
Import-Module ActiveDirectory

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\LDAP_Check_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
$global:ldapServer = $env:COMPUTERNAME  # Default to local machine
$global:ldapPort = 389  # Default LDAP port
$global:ldapsPort = 636  # Default LDAPS port

function Show-Menu {
    Clear-Host
    Write-Host "=== LDAP and LDAPS Check Toolkit ===" -ForegroundColor Cyan
    Write-Host "Current LDAP Server: $global:ldapServer"
    Write-Host "1. Set LDAP Server"
    Write-Host "2. Test LDAP Connectivity"
    Write-Host "3. Test LDAPS Connectivity"
    Write-Host "4. Check LDAP Binding"
    Write-Host "5. Verify LDAP SSL Certificate"
    Write-Host "6. Check LDAP Server Capabilities"
    Write-Host "7. Test LDAP Query"
    Write-Host "8. Check LDAP Security Settings"
    Write-Host "9. Analyze LDAP Traffic"
    Write-Host "10. Generate Comprehensive HTML Report"
    Write-Host "11. Exit"
}

function Set-LDAPServer {
    $server = Read-Host "Enter the LDAP server name (or press Enter for localhost)"
    if ([string]::IsNullOrWhiteSpace($server)) {
        $global:ldapServer = $env:COMPUTERNAME
    } else {
        $global:ldapServer = $server
    }
    Write-Host "LDAP server set to: $global:ldapServer" -ForegroundColor Green
}

function Test-LDAPConnectivity {
    Write-Host "`nTesting LDAP Connectivity..." -ForegroundColor Yellow
    try {
        $result = Test-NetConnection -ComputerName $global:ldapServer -Port $global:ldapPort
        if ($result.TcpTestSucceeded) {
            Write-Host "LDAP connectivity test successful." -ForegroundColor Green
        } else {
            Write-Host "LDAP connectivity test failed." -ForegroundColor Red
        }
        return $result
    }
    catch {
        Write-Host "Error testing LDAP connectivity: $_" -ForegroundColor Red
        return $null
    }
}

function Test-LDAPSConnectivity {
    Write-Host "`nTesting LDAPS Connectivity..." -ForegroundColor Yellow
    try {
        $result = Test-NetConnection -ComputerName $global:ldapServer -Port $global:ldapsPort
        if ($result.TcpTestSucceeded) {
            Write-Host "LDAPS connectivity test successful." -ForegroundColor Green
        } else {
            Write-Host "LDAPS connectivity test failed." -ForegroundColor Red
        }
        return $result
    }
    catch {
        Write-Host "Error testing LDAPS connectivity: $_" -ForegroundColor Red
        return $null
    }
}

function Check-LDAPBinding {
    Write-Host "`nChecking LDAP Binding..." -ForegroundColor Yellow
    try {
        $domainDN = (Get-ADDomain).DistinguishedName
        $ldapPath = "LDAP://$global:ldapServer/$domainDN"
        $ldapConnection = New-Object System.DirectoryServices.DirectoryEntry($ldapPath)
        
        if ($ldapConnection.Name -ne $null) {
            Write-Host "LDAP binding successful." -ForegroundColor Green
            $result = @{
                Success = $true
                Path = $ldapPath
                Name = $ldapConnection.Name
            }
        } else {
            Write-Host "LDAP binding failed." -ForegroundColor Red
            $result = @{
                Success = $false
                Path = $ldapPath
                Error = "Unable to bind to LDAP server"
            }
        }
        return $result
    }
    catch {
        Write-Host "Error checking LDAP binding: $_" -ForegroundColor Red
        return @{
            Success = $false
            Path = $ldapPath
            Error = $_.Exception.Message
        }
    }
}

function Verify-LDAPSSLCertificate {
    Write-Host "`nVerifying LDAP SSL Certificate..." -ForegroundColor Yellow
    try {
        $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
        $cert.Import("LDAP://$global:ldapServer`:$global:ldapsPort")
        
        $result = @{
            Subject = $cert.Subject
            Issuer = $cert.Issuer
            ValidFrom = $cert.NotBefore
            ValidTo = $cert.NotAfter
            Thumbprint = $cert.Thumbprint
        }
        
        if ((Get-Date) -gt $cert.NotAfter) {
            Write-Host "SSL Certificate has expired." -ForegroundColor Red
        } else {
            Write-Host "SSL Certificate is valid." -ForegroundColor Green
        }
        
        return $result
    }
    catch {
        Write-Host "Error verifying LDAP SSL Certificate: $_" -ForegroundColor Red
        return $null
    }
}

function Check-LDAPServerCapabilities {
    Write-Host "`nChecking LDAP Server Capabilities..." -ForegroundColor Yellow
    try {
        $rootDSE = [ADSI]"LDAP://$global:ldapServer/RootDSE"
        $capabilities = $rootDSE.supportedCapabilities
        $ldapVersion = $rootDSE.supportedLDAPVersion
        $controls = $rootDSE.supportedControl
        
        $result = @{
            SupportedCapabilities = $capabilities
            SupportedLDAPVersion = $ldapVersion
            SupportedControls = $controls
        }
        
        Write-Host "LDAP Server Capabilities retrieved successfully." -ForegroundColor Green
        return $result
    }
    catch {
        Write-Host "Error checking LDAP Server Capabilities: $_" -ForegroundColor Red
        return $null
    }
}

function Test-LDAPQuery {
    Write-Host "`nTesting LDAP Query..." -ForegroundColor Yellow
    try {
        $domainDN = (Get-ADDomain).DistinguishedName
        $searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]"LDAP://$global:ldapServer/$domainDN")
        $searcher.Filter = "(objectClass=user)"
        $searcher.SizeLimit = 5
        $results = $searcher.FindAll()
        
        $queryResults = @()
        foreach ($result in $results) {
            $queryResults += [PSCustomObject]@{
                Name = $result.Properties["name"][0]
                DistinguishedName = $result.Properties["distinguishedname"][0]
            }
        }
        
        Write-Host "LDAP Query test successful." -ForegroundColor Green
        return $queryResults
    }
    catch {
        Write-Host "Error testing LDAP Query: $_" -ForegroundColor Red
        return $null
    }
}

function Check-LDAPSecuritySettings {
    Write-Host "`nChecking LDAP Security Settings..." -ForegroundColor Yellow
    try {
        $ntdsSettings = Get-ADObject -Identity "CN=NTDS Settings,CN=$global:ldapServer,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,$((Get-ADDomain).DistinguishedName)" -Properties *
        
        $result = @{
            LDAPServerSigningRequired = $ntdsSettings.LDAPServerIntegrity -eq 2
            LDAPSEnabled = $ntdsSettings.SSLPort -ne $null
            NTLMAuthEnabled = $ntdsSettings.SupportedSASLMechanisms -contains "GSSAPI"
            KerberosAuthEnabled = $ntdsSettings.SupportedSASLMechanisms -contains "GSS-SPNEGO"
        }
        
        Write-Host "LDAP Security Settings retrieved successfully." -ForegroundColor Green
        return $result
    }
    catch {
        Write-Host "Error checking LDAP Security Settings: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-LDAPTraffic {
    Write-Host "`nAnalyzing LDAP Traffic..." -ForegroundColor Yellow
    Write-Host "This function would typically use network monitoring tools to analyze LDAP traffic."
    Write-Host "For security and complexity reasons, actual traffic analysis is not implemented in this script."
    Write-Host "Consider using tools like Wireshark or Microsoft Network Monitor for detailed LDAP traffic analysis."
    
    # Placeholder for traffic analysis results
    $result = @{
        TotalConnections = "N/A"
        AverageResponseTime = "N/A"
        ErrorRate = "N/A"
    }
    
    return $result
}

function Generate-HTMLReport {
    param([hashtable]$AllResults)

    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>LDAP and LDAPS Check Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .success { color: green; }
        .warning { color: orange; }
        .error { color: red; }
    </style>
</head>
<body>
    <h1>LDAP and LDAPS Check Report</h1>
    <p>Generated on: $(Get-Date)</p>
    <p>LDAP Server: $global:ldapServer</p>

    <h2>LDAP Connectivity</h2>
    $($AllResults.LDAPConnectivity | ConvertTo-Html -Fragment)

    <h2>LDAPS Connectivity</h2>
    $($AllResults.LDAPSConnectivity | ConvertTo-Html -Fragment)

    <h2>LDAP Binding</h2>
    $($AllResults.LDAPBinding | ConvertTo-Html -Fragment)

    <h2>LDAP SSL Certificate</h2>
    $($AllResults.LDAPSSLCertificate | ConvertTo-Html -Fragment)

    <h2>LDAP Server Capabilities</h2>
    $($AllResults.ServerCapabilities | ConvertTo-Html -Fragment)

    <h2>LDAP Query Test</h2>
    $($AllResults.LDAPQuery | ConvertTo-Html -Fragment)

    <h2>LDAP Security Settings</h2>
    $($AllResults.SecuritySettings | ConvertTo-Html -Fragment)

    <h2>LDAP Traffic Analysis</h2>
    $($AllResults.TrafficAnalysis | ConvertTo-Html -Fragment)
</body>
</html>
"@

    $reportContent | Out-File -FilePath $global:reportPath
    Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green
}

# Main program loop
$allResults = @{}

do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-11)"

    switch ($choice) {
        "1" { Set-LDAPServer }
        "2" { $allResults.LDAPConnectivity = Test-LDAPConnectivity }
        "3" { $allResults.LDAPSConnectivity = Test-LDAPSConnectivity }
        "4" { $allResults.LDAPBinding = Check-LDAPBinding }
        "5" { $allResults.LDAPSSLCertificate = Verify-LDAPSSLCertificate }
        "6" { $allResults.ServerCapabilities = Check-LDAPServerCapabilities }
        "7" { $allResults.LDAPQuery = Test-LDAPQuery }
        "8" { $allResults.SecuritySettings = Check-LDAPSecuritySettings }
        "9" { $allResults.TrafficAnalysis = Analyze-LDAPTraffic }
        "10" { Generate-HTMLReport -AllResults $allResults }
        "11" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "11") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "11")

This LDAP and LDAPS Check Toolkit includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze and test various aspects of LDAP and LDAPS:
    • LDAP and LDAPS Connectivity Tests
    • LDAP Binding Check
    • LDAP SSL Certificate Verification
    • LDAP Server Capabilities Check
    • LDAP Query Test
    • LDAP Security Settings Check
    • LDAP Traffic Analysis (placeholder)
  3. Option to set a target LDAP server (local or remote)
  4. HTML report generation for easy sharing and viewing of results

Key features:

  • Comprehensive LDAP and LDAPS connectivity testing
  • Detailed SSL certificate verification for LDAPS
  • Analysis of LDAP server capabilities and supported features
  • Basic LDAP query testing
  • Review of LDAP security settings
  • Placeholder for LDAP traffic analysis (which would typically require additional tools)

This tool is particularly useful for:

  • System administrators managing LDAP-enabled environments
  • Security professionals auditing LDAP configurations
  • IT professionals troubleshooting LDAP-related issues
  • Anyone needing to quickly gather comprehensive information about LDAP and LDAPS configurations

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the Active Directory PowerShell module installed
  3. Have the necessary permissions to query LDAP server information
  4. Review the generated HTML report for a comprehensive overview of the LDAP server’s configuration and status

Note: The LDAP traffic analysis function is a placeholder and would typically require additional network monitoring tools to implement fully. For actual traffic analysis, consider using specialized tools like Wireshark or Microsoft Network Monitor.

This script provides a thorough analysis of LDAP and LDAPS configurations, helping to identify potential issues, misconfigurations, or security concerns. It’s designed to give administrators a quick but comprehensive view of their LDAP server’s health and configuration.

IP Configuration Toolkit

<#
.SYNOPSIS
IP Configuration Toolkit

.DESCRIPTION
This script provides comprehensive analysis and management options for IP configurations on Windows systems.

.NOTES
File Name      : IPConfigToolkit.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, and appropriate admin rights
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\IPConfigToolkit.ps1
#>

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\IP_Config_Analysis_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
$global:targetComputer = $env:COMPUTERNAME  # Default to local machine

function Show-Menu {
    Clear-Host
    Write-Host "=== IP Configuration Toolkit ===" -ForegroundColor Cyan
    Write-Host "Current Target Computer: $global:targetComputer"
    Write-Host "1. Set Target Computer"
    Write-Host "2. Get IP Configuration"
    Write-Host "3. Analyze Network Adapters"
    Write-Host "4. Check DNS Settings"
    Write-Host "5. Perform Network Connectivity Tests"
    Write-Host "6. View Routing Table"
    Write-Host "7. Check Network Shares"
    Write-Host "8. Analyze Open Ports"
    Write-Host "9. View Network Statistics"
    Write-Host "10. Generate Comprehensive HTML Report"
    Write-Host "11. Exit"
}

function Set-TargetComputer {
    $computer = Read-Host "Enter the target computer name (or press Enter for localhost)"
    if ([string]::IsNullOrWhiteSpace($computer)) {
        $global:targetComputer = $env:COMPUTERNAME
    } else {
        $global:targetComputer = $computer
    }
    Write-Host "Target computer set to: $global:targetComputer" -ForegroundColor Green
}

function Get-IPConfiguration {
    Write-Host "`nGathering IP Configuration..." -ForegroundColor Yellow
    try {
        $ipConfig = Invoke-Command -ComputerName $global:targetComputer -ScriptBlock {
            Get-NetIPConfiguration | Select-Object InterfaceAlias, IPv4Address, IPv6Address, DNSServer
        }
        $ipConfig | Format-Table -AutoSize
        return $ipConfig
    }
    catch {
        Write-Host "Error getting IP configuration: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-NetworkAdapters {
    Write-Host "`nAnalyzing Network Adapters..." -ForegroundColor Yellow
    try {
        $adapters = Invoke-Command -ComputerName $global:targetComputer -ScriptBlock {
            Get-NetAdapter | Select-Object Name, InterfaceDescription, Status, LinkSpeed, MacAddress
        }
        $adapters | Format-Table -AutoSize
        return $adapters
    }
    catch {
        Write-Host "Error analyzing network adapters: $_" -ForegroundColor Red
        return $null
    }
}

function Check-DNSSettings {
    Write-Host "`nChecking DNS Settings..." -ForegroundColor Yellow
    try {
        $dnsSettings = Invoke-Command -ComputerName $global:targetComputer -ScriptBlock {
            Get-DnsClientServerAddress | Select-Object InterfaceAlias, ServerAddresses
        }
        $dnsSettings | Format-Table -AutoSize
        return $dnsSettings
    }
    catch {
        Write-Host "Error checking DNS settings: $_" -ForegroundColor Red
        return $null
    }
}

function Perform-NetworkConnectivityTests {
    Write-Host "`nPerforming Network Connectivity Tests..." -ForegroundColor Yellow
    try {
        $results = @()
        $testTargets = @("8.8.8.8", "www.google.com", $global:targetComputer)
        foreach ($target in $testTargets) {
            $pingResult = Test-Connection -ComputerName $target -Count 4 -ErrorAction SilentlyContinue
            $results += [PSCustomObject]@{
                Target = $target
                Successful = if ($pingResult) { $true } else { $false }
                AverageResponseTime = if ($pingResult) { ($pingResult | Measure-Object -Property ResponseTime -Average).Average } else { "N/A" }
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error performing network connectivity tests: $_" -ForegroundColor Red
        return $null
    }
}

function View-RoutingTable {
    Write-Host "`nViewing Routing Table..." -ForegroundColor Yellow
    try {
        $routes = Invoke-Command -ComputerName $global:targetComputer -ScriptBlock {
            Get-NetRoute | Select-Object DestinationPrefix, NextHop, RouteMetric, InterfaceAlias
        }
        $routes | Format-Table -AutoSize
        return $routes
    }
    catch {
        Write-Host "Error viewing routing table: $_" -ForegroundColor Red
        return $null
    }
}

function Check-NetworkShares {
    Write-Host "`nChecking Network Shares..." -ForegroundColor Yellow
    try {
        $shares = Invoke-Command -ComputerName $global:targetComputer -ScriptBlock {
            Get-SmbShare | Select-Object Name, Path, Description
        }
        $shares | Format-Table -AutoSize
        return $shares
    }
    catch {
        Write-Host "Error checking network shares: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-OpenPorts {
    Write-Host "`nAnalyzing Open Ports..." -ForegroundColor Yellow
    try {
        $openPorts = Invoke-Command -ComputerName $global:targetComputer -ScriptBlock {
            Get-NetTCPConnection | Where-Object State -eq 'Listen' | Select-Object LocalAddress, LocalPort, State, OwningProcess
        }
        $openPorts | Format-Table -AutoSize
        return $openPorts
    }
    catch {
        Write-Host "Error analyzing open ports: $_" -ForegroundColor Red
        return $null
    }
}

function View-NetworkStatistics {
    Write-Host "`nViewing Network Statistics..." -ForegroundColor Yellow
    try {
        $stats = Invoke-Command -ComputerName $global:targetComputer -ScriptBlock {
            $tcpStats = Get-NetTCPConnection | Group-Object State | Select-Object Name, Count
            $ipStats = Get-NetIPv4Protocol | Select-Object DefaultHopLimit, NeighborCacheLimit, RouteCacheLimit
            return @{
                TCPConnections = $tcpStats
                IPv4Stats = $ipStats
            }
        }
        $stats.TCPConnections | Format-Table -AutoSize
        $stats.IPv4Stats | Format-List
        return $stats
    }
    catch {
        Write-Host "Error viewing network statistics: $_" -ForegroundColor Red
        return $null
    }
}

function Generate-HTMLReport {
    param([hashtable]$AllResults)

    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IP Configuration Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .warning { color: orange; }
        .critical { color: red; }
    </style>
</head>
<body>
    <h1>IP Configuration Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>
    <p>Target Computer: $global:targetComputer</p>

    <h2>IP Configuration</h2>
    $($AllResults.IPConfig | ConvertTo-Html -Fragment)

    <h2>Network Adapters</h2>
    $($AllResults.NetworkAdapters | ConvertTo-Html -Fragment)

    <h2>DNS Settings</h2>
    $($AllResults.DNSSettings | ConvertTo-Html -Fragment)

    <h2>Network Connectivity Tests</h2>
    $($AllResults.ConnectivityTests | ConvertTo-Html -Fragment)

    <h2>Routing Table</h2>
    $($AllResults.RoutingTable | ConvertTo-Html -Fragment)

    <h2>Network Shares</h2>
    $($AllResults.NetworkShares | ConvertTo-Html -Fragment)

    <h2>Open Ports</h2>
    $($AllResults.OpenPorts | ConvertTo-Html -Fragment)

    <h2>Network Statistics</h2>
    <h3>TCP Connections</h3>
    $($AllResults.NetworkStats.TCPConnections | ConvertTo-Html -Fragment)
    <h3>IPv4 Statistics</h3>
    $($AllResults.NetworkStats.IPV4Stats | ConvertTo-Html -Fragment)
</body>
</html>
"@

    $reportContent | Out-File -FilePath $global:reportPath
    Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green
}

# Main program loop
$allResults = @{}

do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-11)"

    switch ($choice) {
        "1" { Set-TargetComputer }
        "2" { $allResults.IPConfig = Get-IPConfiguration }
        "3" { $allResults.NetworkAdapters = Analyze-NetworkAdapters }
        "4" { $allResults.DNSSettings = Check-DNSSettings }
        "5" { $allResults.ConnectivityTests = Perform-NetworkConnectivityTests }
        "6" { $allResults.RoutingTable = View-RoutingTable }
        "7" { $allResults.NetworkShares = Check-NetworkShares }
        "8" { $allResults.OpenPorts = Analyze-OpenPorts }
        "9" { $allResults.NetworkStats = View-NetworkStatistics }
        "10" { Generate-HTMLReport -AllResults $allResults }
        "11" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "11") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "11")

This IP Configuration Toolkit includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze and manage various aspects of IP configurations:
    • IP Configuration retrieval
    • Network Adapter analysis
    • DNS Settings check
    • Network Connectivity Tests
    • Routing Table view
    • Network Shares check
    • Open Ports analysis
    • Network Statistics view
  3. Option to set a target computer (local or remote)
  4. HTML report generation for easy sharing and viewing of results

Key features:

  • Comprehensive IP configuration information gathering
  • Detailed analysis of network adapters
  • DNS settings review
  • Network connectivity tests to key targets
  • Routing table examination
  • Network shares enumeration
  • Open ports analysis for security review
  • Network statistics overview

This tool is particularly useful for:

  • Network administrators troubleshooting IP configuration issues
  • System administrators performing network health checks
  • IT professionals analyzing network setups on remote systems
  • Security analysts reviewing open ports and network configurations

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query network information on the target computer
  3. For remote computer analysis, make sure you have appropriate network access and permissions
  4. Review the generated HTML report for a comprehensive overview of the IP configuration and network status

This script provides a thorough analysis of IP configurations and related network settings, helping to identify potential issues, misconfigurations, or areas that need attention. It’s designed to give administrators a quick but comprehensive view of a system’s network configuration and status.

DHCP Toolkit

<#
.SYNOPSIS
DHCP Toolkit

.DESCRIPTION
This script provides comprehensive analysis and management options for DHCP servers in a Windows environment.

.NOTES
File Name      : DHCPToolkit.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, DHCP Server module, and appropriate admin rights
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\DHCPToolkit.ps1
#>

# Import required module
Import-Module DHCPServer

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\DHCP_Analysis_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
$global:dhcpServer = $env:COMPUTERNAME  # Default to local machine

function Show-Menu {
    Clear-Host
    Write-Host "=== DHCP Toolkit ===" -ForegroundColor Cyan
    Write-Host "Current DHCP Server: $global:dhcpServer"
    Write-Host "1. Set DHCP Server"
    Write-Host "2. Get DHCP Server Information"
    Write-Host "3. List DHCP Scopes"
    Write-Host "4. Analyze Scope Utilization"
    Write-Host "5. Check DHCP Options"
    Write-Host "6. List DHCP Reservations"
    Write-Host "7. Check DHCP Failover Configuration"
    Write-Host "8. Analyze DHCP Lease History"
    Write-Host "9. Check DHCP Server Statistics"
    Write-Host "10. Generate Comprehensive HTML Report"
    Write-Host "11. Exit"
}

function Set-DHCPServer {
    $server = Read-Host "Enter the DHCP server name (or press Enter for localhost)"
    if ([string]::IsNullOrWhiteSpace($server)) {
        $global:dhcpServer = $env:COMPUTERNAME
    } else {
        $global:dhcpServer = $server
    }
    Write-Host "DHCP server set to: $global:dhcpServer" -ForegroundColor Green
}

function Get-DHCPServerInformation {
    Write-Host "`nGathering DHCP Server Information..." -ForegroundColor Yellow
    try {
        $serverInfo = Get-DhcpServerSetting -ComputerName $global:dhcpServer
        $result = [PSCustomObject]@{
            ServerName = $global:dhcpServer
            ConflictDetectionAttempts = $serverInfo.ConflictDetectionAttempts
            DynamicBootp = $serverInfo.DynamicBootp
            IsAuthorized = $serverInfo.IsAuthorized
            NapEnabled = $serverInfo.NapEnabled
            RestoreStatus = $serverInfo.RestoreStatus
        }
        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error getting DHCP server information: $_" -ForegroundColor Red
        return $null
    }
}

function Get-DHCPScopes {
    Write-Host "`nListing DHCP Scopes..." -ForegroundColor Yellow
    try {
        $scopes = Get-DhcpServerv4Scope -ComputerName $global:dhcpServer
        $scopes | Format-Table -AutoSize
        return $scopes
    }
    catch {
        Write-Host "Error getting DHCP scopes: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-ScopeUtilization {
    Write-Host "`nAnalyzing Scope Utilization..." -ForegroundColor Yellow
    try {
        $scopes = Get-DhcpServerv4Scope -ComputerName $global:dhcpServer
        $results = @()
        foreach ($scope in $scopes) {
            $stats = Get-DhcpServerv4ScopeStatistics -ComputerName $global:dhcpServer -ScopeId $scope.ScopeId
            $results += [PSCustomObject]@{
                ScopeName = $scope.Name
                ScopeId = $scope.ScopeId
                TotalAddresses = $stats.TotalAddresses
                InUse = $stats.AddressesInUse
                Available = $stats.AddressesAvailable
                UtilizationPercentage = [math]::Round(($stats.AddressesInUse / $stats.TotalAddresses) * 100, 2)
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error analyzing scope utilization: $_" -ForegroundColor Red
        return $null
    }
}

function Check-DHCPOptions {
    Write-Host "`nChecking DHCP Options..." -ForegroundColor Yellow
    try {
        $serverOptions = Get-DhcpServerv4OptionValue -ComputerName $global:dhcpServer
        $scopeOptions = Get-DhcpServerv4Scope -ComputerName $global:dhcpServer | ForEach-Object {
            Get-DhcpServerv4OptionValue -ComputerName $global:dhcpServer -ScopeId $_.ScopeId
        }
        
        $results = @{
            ServerOptions = $serverOptions
            ScopeOptions = $scopeOptions
        }
        
        $serverOptions | Format-Table -AutoSize
        Write-Host "Scope-specific options are available in the returned object." -ForegroundColor Yellow
        return $results
    }
    catch {
        Write-Host "Error checking DHCP options: $_" -ForegroundColor Red
        return $null
    }
}

function List-DHCPReservations {
    Write-Host "`nListing DHCP Reservations..." -ForegroundColor Yellow
    try {
        $scopes = Get-DhcpServerv4Scope -ComputerName $global:dhcpServer
        $results = @()
        foreach ($scope in $scopes) {
            $reservations = Get-DhcpServerv4Reservation -ComputerName $global:dhcpServer -ScopeId $scope.ScopeId
            foreach ($reservation in $reservations) {
                $results += [PSCustomObject]@{
                    ScopeId = $scope.ScopeId
                    IPAddress = $reservation.IPAddress
                    ClientId = $reservation.ClientId
                    Name = $reservation.Name
                }
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error listing DHCP reservations: $_" -ForegroundColor Red
        return $null
    }
}

function Check-DHCPFailover {
    Write-Host "`nChecking DHCP Failover Configuration..." -ForegroundColor Yellow
    try {
        $failoverRelationships = Get-DhcpServerv4Failover -ComputerName $global:dhcpServer
        if ($failoverRelationships) {
            $failoverRelationships | Format-Table -AutoSize
        } else {
            Write-Host "No failover relationships configured." -ForegroundColor Yellow
        }
        return $failoverRelationships
    }
    catch {
        Write-Host "Error checking DHCP failover configuration: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-DHCPLeaseHistory {
    Write-Host "`nAnalyzing DHCP Lease History..." -ForegroundColor Yellow
    try {
        $startDate = (Get-Date).AddDays(-7)
        $leaseHistory = Get-DhcpServerv4ScopeStatistics -ComputerName $global:dhcpServer | ForEach-Object {
            Get-DhcpServerv4LeaseHistory -ComputerName $global:dhcpServer -ScopeId $_.ScopeId -StartDate $startDate
        }
        
        $results = $leaseHistory | Group-Object ScopeId | ForEach-Object {
            [PSCustomObject]@{
                ScopeId = $_.Name
                LeaseCount = $_.Count
                UniqueClients = ($_.Group | Select-Object -ExpandProperty ClientId -Unique).Count
            }
        }
        
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error analyzing DHCP lease history: $_" -ForegroundColor Red
        return $null
    }
}

function Check-DHCPServerStatistics {
    Write-Host "`nChecking DHCP Server Statistics..." -ForegroundColor Yellow
    try {
        $stats = Get-DhcpServerStatistics -ComputerName $global:dhcpServer
        $result = [PSCustomObject]@{
            TotalScopes = $stats.TotalScopes
            TotalAddresses = $stats.TotalAddresses
            AddressesInUse = $stats.AddressesInUse
            AddressesAvailable = $stats.AddressesAvailable
            PercentageInUse = [math]::Round(($stats.AddressesInUse / $stats.TotalAddresses) * 100, 2)
            Discovers = $stats.Discovers
            Offers = $stats.Offers
            Requests = $stats.Requests
            Acks = $stats.Acks
            Naks = $stats.Naks
            Declines = $stats.Declines
            Releases = $stats.Releases
        }
        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error checking DHCP server statistics: $_" -ForegroundColor Red
        return $null
    }
}

function Generate-HTMLReport {
    param([hashtable]$AllResults)

    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DHCP Server Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .warning { color: orange; }
        .critical { color: red; }
    </style>
</head>
<body>
    <h1>DHCP Server Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>
    <p>DHCP Server: $global:dhcpServer</p>

    <h2>DHCP Server Information</h2>
    $($AllResults.ServerInfo | ConvertTo-Html -Fragment)

    <h2>DHCP Scopes</h2>
    $($AllResults.Scopes | ConvertTo-Html -Fragment)

    <h2>Scope Utilization</h2>
    $($AllResults.ScopeUtilization | ConvertTo-Html -Fragment)

    <h2>DHCP Options</h2>
    <h3>Server Options</h3>
    $($AllResults.DHCPOptions.ServerOptions | ConvertTo-Html -Fragment)

    <h2>DHCP Reservations</h2>
    $($AllResults.Reservations | ConvertTo-Html -Fragment)

    <h2>DHCP Failover Configuration</h2>
    $($AllResults.FailoverConfig | ConvertTo-Html -Fragment)

    <h2>DHCP Lease History (Last 7 Days)</h2>
    $($AllResults.LeaseHistory | ConvertTo-Html -Fragment)

    <h2>DHCP Server Statistics</h2>
    $($AllResults.ServerStats | ConvertTo-Html -Fragment)
</body>
</html>
"@

    $reportContent | Out-File -FilePath $global:reportPath
    Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green
}

# Main program loop
$allResults = @{}

do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-11)"

    switch ($choice) {
        "1" { Set-DHCPServer }
        "2" { $allResults.ServerInfo = Get-DHCPServerInformation }
        "3" { $allResults.Scopes = Get-DHCPScopes }
        "4" { $allResults.ScopeUtilization = Analyze-ScopeUtilization }
        "5" { $allResults.DHCPOptions = Check-DHCPOptions }
        "6" { $allResults.Reservations = List-DHCPReservations }
        "7" { $allResults.FailoverConfig = Check-DHCPFailover }
        "8" { $allResults.LeaseHistory = Analyze-DHCPLeaseHistory }
        "9" { $allResults.ServerStats = Check-DHCPServerStatistics }
        "10" { Generate-HTMLReport -AllResults $allResults }
        "11" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "11") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "11")

This DHCP Toolkit includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze and manage various aspects of DHCP servers:
    • DHCP Server Information
    • DHCP Scopes Listing
    • Scope Utilization Analysis
    • DHCP Options Check
    • DHCP Reservations Listing
    • DHCP Failover Configuration Check
    • DHCP Lease History Analysis
    • DHCP Server Statistics Check
  3. Option to set a target DHCP server (local or remote)
  4. HTML report generation for easy sharing and viewing of results

Key features:

  • Comprehensive DHCP server information gathering
  • Detailed analysis of scope utilization
  • Review of DHCP options at server and scope level
  • Listing of DHCP reservations across all scopes
  • Failover configuration check
  • Analysis of recent lease history
  • Overview of DHCP server statistics

This tool is particularly useful for:

  • Network administrators managing DHCP servers
  • IT professionals troubleshooting DHCP-related issues
  • System administrators performing regular DHCP health checks
  • Anyone needing to quickly gather comprehensive information about DHCP server configurations

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the DHCP Server PowerShell module installed (typically available on DHCP servers or management workstations)
  3. Have the necessary permissions to query DHCP server information (local admin rights on the DHCP server or appropriate delegated permissions)
  4. Review the generated HTML report for a comprehensive overview of the DHCP server’s configuration and status

This script provides a thorough analysis of a DHCP server, helping to identify potential issues, misconfigurations, or areas that need attention. It’s designed to give administrators a quick but comprehensive view of their DHCP server’s health and configuration.

Domain Check Toolkit

<#
.SYNOPSIS
Domain Check Toolkit

.DESCRIPTION
This script performs comprehensive checks and information gathering on an Active Directory domain,
providing insights into domain controllers, users, groups, GPOs, and other domain-related configurations.

.NOTES
File Name      : DomainCheckToolkit.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, Active Directory module, and appropriate domain admin rights
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\DomainCheckToolkit.ps1
#>

# Import required modules
Import-Module ActiveDirectory

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\Domain_Check_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"

function Show-Menu {
    Clear-Host
    Write-Host "=== Domain Check Toolkit ===" -ForegroundColor Cyan
    Write-Host "1. Domain Information"
    Write-Host "2. Domain Controller Health Check"
    Write-Host "3. User Account Analysis"
    Write-Host "4. Group Analysis"
    Write-Host "5. Group Policy Object (GPO) Check"
    Write-Host "6. DNS Health Check"
    Write-Host "7. FSMO Roles Check"
    Write-Host "8. Replication Status"
    Write-Host "9. Trust Relationships"
    Write-Host "10. Generate Comprehensive HTML Report"
    Write-Host "11. Exit"
}

function Get-DomainInformation {
    Write-Host "`nGathering Domain Information..." -ForegroundColor Yellow
    $domainInfo = Get-ADDomain
    $forestInfo = Get-ADForest

    $result = [PSCustomObject]@{
        DomainName = $domainInfo.DNSRoot
        NetBIOSName = $domainInfo.NetBIOSName
        DomainMode = $domainInfo.DomainMode
        ForestName = $forestInfo.Name
        ForestMode = $forestInfo.ForestMode
        DomainControllers = ($domainInfo.ReplicaDirectoryServers -join ", ")
        GlobalCatalogs = ($forestInfo.GlobalCatalogs -join ", ")
    }

    $result | Format-List
    return $result
}

function Get-DomainControllerHealth {
    Write-Host "`nPerforming Domain Controller Health Check..." -ForegroundColor Yellow
    $dcs = Get-ADDomainController -Filter *
    $results = @()

    foreach ($dc in $dcs) {
        $dcdiag = dcdiag /s:$($dc.HostName) /test:services /test:advertising /test:fsmocheck /test:ridmanager
        $results += [PSCustomObject]@{
            Name = $dc.HostName
            Site = $dc.Site
            IPv4Address = $dc.IPv4Address
            OperatingSystem = $dc.OperatingSystem
            IsGlobalCatalog = $dc.IsGlobalCatalog
            ServicesTest = if ($dcdiag -match "passed test Services") { "Passed" } else { "Failed" }
            AdvertisingTest = if ($dcdiag -match "passed test Advertising") { "Passed" } else { "Failed" }
            FSMOCheckTest = if ($dcdiag -match "passed test FsmoCheck") { "Passed" } else { "Failed" }
            RidManagerTest = if ($dcdiag -match "passed test RidManager") { "Passed" } else { "Failed" }
        }
    }

    $results | Format-Table -AutoSize
    return $results
}

function Get-UserAccountAnalysis {
    Write-Host "`nPerforming User Account Analysis..." -ForegroundColor Yellow
    $users = Get-ADUser -Filter * -Properties Enabled, PasswordLastSet, LastLogonDate, PasswordNeverExpires
    $results = @{
        TotalUsers = $users.Count
        EnabledUsers = ($users | Where-Object { $_.Enabled -eq $true }).Count
        DisabledUsers = ($users | Where-Object { $_.Enabled -eq $false }).Count
        PasswordNeverExpires = ($users | Where-Object { $_.PasswordNeverExpires -eq $true }).Count
        InactiveUsers = ($users | Where-Object { $_.LastLogonDate -lt (Get-Date).AddDays(-90) }).Count
    }

    $results | Format-Table -AutoSize
    return $results
}

function Get-GroupAnalysis {
    Write-Host "`nPerforming Group Analysis..." -ForegroundColor Yellow
    $groups = Get-ADGroup -Filter *
    $results = @{
        TotalGroups = $groups.Count
        SecurityGroups = ($groups | Where-Object { $_.GroupCategory -eq "Security" }).Count
        DistributionGroups = ($groups | Where-Object { $_.GroupCategory -eq "Distribution" }).Count
        GlobalGroups = ($groups | Where-Object { $_.GroupScope -eq "Global" }).Count
        UniversalGroups = ($groups | Where-Object { $_.GroupScope -eq "Universal" }).Count
        DomainLocalGroups = ($groups | Where-Object { $_.GroupScope -eq "DomainLocal" }).Count
    }

    $results | Format-Table -AutoSize
    return $results
}

function Get-GPOCheck {
    Write-Host "`nPerforming Group Policy Object Check..." -ForegroundColor Yellow
    $gpos = Get-GPO -All
    $results = @()

    foreach ($gpo in $gpos) {
        $results += [PSCustomObject]@{
            Name = $gpo.DisplayName
            ID = $gpo.Id
            CreationTime = $gpo.CreationTime
            ModificationTime = $gpo.ModificationTime
            UserVersionNumber = $gpo.UserVersion.DSVersion
            ComputerVersionNumber = $gpo.ComputerVersion.DSVersion
        }
    }

    $results | Format-Table -AutoSize
    return $results
}

function Get-DNSHealthCheck {
    Write-Host "`nPerforming DNS Health Check..." -ForegroundColor Yellow
    $dnsServers = Get-ADDomainController -Filter * | Select-Object -ExpandProperty Name
    $results = @()

    foreach ($server in $dnsServers) {
        $dnsTest = Test-DnsServer -ComputerName $server -Context DnsServer
        $results += [PSCustomObject]@{
            Server = $server
            IsResponding = $dnsTest.IsResponding
            TCPPort53Open = ($dnsTest.TcpOpen -contains 53)
            UDPPort53Open = ($dnsTest.UdpOpen -contains 53)
        }
    }

    $results | Format-Table -AutoSize
    return $results
}

function Get-FSMORolesCheck {
    Write-Host "`nChecking FSMO Roles..." -ForegroundColor Yellow
    $domain = Get-ADDomain
    $forest = Get-ADForest

    $result = [PSCustomObject]@{
        PDCEmulator = $domain.PDCEmulator
        RIDMaster = $domain.RIDMaster
        InfrastructureMaster = $domain.InfrastructureMaster
        SchemaMaster = $forest.SchemaMaster
        DomainNamingMaster = $forest.DomainNamingMaster
    }

    $result | Format-List
    return $result
}

function Get-ReplicationStatus {
    Write-Host "`nChecking Replication Status..." -ForegroundColor Yellow
    $results = @()
    $repl = repadmin /showrepl * /csv
    $replData = ConvertFrom-Csv $repl

    foreach ($item in $replData) {
        if ($item."Number of Failures" -ne "0") {
            $results += [PSCustomObject]@{
                SourceDC = $item."Source DC"
                DestinationDC = $item."Destination DC"
                FailureCount = $item."Number of Failures"
                LastFailureTime = $item."Last Failure Time"
                LastSuccessTime = $item."Last Success Time"
            }
        }
    }

    if ($results.Count -eq 0) {
        Write-Host "No replication failures detected." -ForegroundColor Green
    } else {
        $results | Format-Table -AutoSize
    }
    return $results
}

function Get-TrustRelationships {
    Write-Host "`nChecking Trust Relationships..." -ForegroundColor Yellow
    $trusts = Get-ADTrust -Filter *
    $results = @()

    foreach ($trust in $trusts) {
        $results += [PSCustomObject]@{
            Name = $trust.Name
            Direction = $trust.Direction
            TrustType = $trust.TrustType
            ForestTransitive = $trust.ForestTransitive
            IntraForest = $trust.IntraForest
        }
    }

    $results | Format-Table -AutoSize
    return $results
}

function Generate-HTMLReport {
    param([hashtable]$AllResults)

    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Domain Check Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .warning { color: orange; }
        .critical { color: red; }
    </style>
</head>
<body>
    <h1>Domain Check Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>Domain Information</h2>
    $($AllResults.DomainInfo | ConvertTo-Html -Fragment)

    <h2>Domain Controller Health</h2>
    $($AllResults.DCHealth | ConvertTo-Html -Fragment)

    <h2>User Account Analysis</h2>
    $($AllResults.UserAnalysis | ConvertTo-Html -Fragment)

    <h2>Group Analysis</h2>
    $($AllResults.GroupAnalysis | ConvertTo-Html -Fragment)

    <h2>Group Policy Objects</h2>
    $($AllResults.GPOCheck | ConvertTo-Html -Fragment)

    <h2>DNS Health Check</h2>
    $($AllResults.DNSHealth | ConvertTo-Html -Fragment)

    <h2>FSMO Roles</h2>
    $($AllResults.FSMORoles | ConvertTo-Html -Fragment)

    <h2>Replication Status</h2>
    $($AllResults.ReplicationStatus | ConvertTo-Html -Fragment)

    <h2>Trust Relationships</h2>
    $($AllResults.TrustRelationships | ConvertTo-Html -Fragment)
</body>
</html>
"@

    $reportContent | Out-File -FilePath $global:reportPath
    Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green
}

# Main program loop
$allResults = @{}

do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-11)"

    switch ($choice) {
        "1" { $allResults.DomainInfo = Get-DomainInformation }
        "2" { $allResults.DCHealth = Get-DomainControllerHealth }
        "3" { $allResults.UserAnalysis = Get-UserAccountAnalysis }
        "4" { $allResults.GroupAnalysis = Get-GroupAnalysis }
        "5" { $allResults.GPOCheck = Get-GPOCheck }
        "6" { $allResults.DNSHealth = Get-DNSHealthCheck }
        "7" { $allResults.FSMORoles = Get-FSMORolesCheck }
        "8" { $allResults.ReplicationStatus = Get-ReplicationStatus }
        "9" { $allResults.TrustRelationships = Get-TrustRelationships }
        "10" { Generate-HTMLReport -AllResults $allResults }
        "11" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "11") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "11")

This Domain Check Toolkit includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of the Active Directory domain:
    • Domain Information
    • Domain Controller Health Check
    • User Account Analysis
    • Group Analysis
    • Group Policy Object (GPO) Check
    • DNS Health Check
    • FSMO Roles Check
    • Replication Status
    • Trust Relationships
  3. HTML report generation for easy sharing and viewing of results.

Key features:

  • Comprehensive domain information gathering
  • Health check of all domain controllers
  • Analysis of user accounts, including inactive and potentially insecure accounts
  • Overview of group distribution in the domain
  • GPO inventory and version checking
  • DNS server health verification
  • FSMO roles location check
  • Replication status and failure detection
  • Trust relationship enumeration

This tool is particularly useful for:

  • Domain administrators performing regular health checks
  • IT professionals troubleshooting domain-wide issues
  • Security auditors reviewing domain configurations
  • Anyone needing to quickly gather comprehensive information about an Active Directory domain

To use this script effectively:

  1. Run PowerShell as an administrator on a domain-joined machine (preferably a domain controller)
  2. Ensure you have the necessary permissions to query domain information (Domain Admin or equivalent rights)
  3. Have the Active Directory PowerShell module installed
  4. Review the generated HTML report for a comprehensive overview of the domain’s status and configuration

This script provides a thorough check of an Active Directory domain, helping to identify potential issues, misconfigurations, or security concerns. It’s designed to give administrators a quick but comprehensive view of their domain’s health and configuration.

Local Windows Client Audit Toolkit

<#
.SYNOPSIS
Local Windows Client Audit Toolkit

.DESCRIPTION
This script performs a comprehensive audit of a local Windows client machine,
gathering information about hardware, software, security settings, and more.

.NOTES
File Name      : LocalWindowsClientAuditToolkit.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, administrator rights
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\LocalWindowsClientAuditToolkit.ps1
#>

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\Windows_Client_Audit_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"

function Show-Menu {
    Clear-Host
    Write-Host "=== Local Windows Client Audit Toolkit ===" -ForegroundColor Cyan
    Write-Host "1. System Information"
    Write-Host "2. Hardware Inventory"
    Write-Host "3. Installed Software"
    Write-Host "4. Windows Update Status"
    Write-Host "5. Security Settings"
    Write-Host "6. Network Configuration"
    Write-Host "7. User Accounts and Groups"
    Write-Host "8. Startup Programs"
    Write-Host "9. Disk Space and File System"
    Write-Host "10. Event Log Analysis"
    Write-Host "11. Generate Comprehensive HTML Report"
    Write-Host "12. Exit"
}

function Get-SystemInformation {
    Write-Host "`nGathering System Information..." -ForegroundColor Yellow
    $os = Get-CimInstance Win32_OperatingSystem
    $cs = Get-CimInstance Win32_ComputerSystem
    $result = [PSCustomObject]@{
        ComputerName = $env:COMPUTERNAME
        OSName = $os.Caption
        OSVersion = $os.Version
        OSArchitecture = $os.OSArchitecture
        LastBootUpTime = $os.LastBootUpTime
        Manufacturer = $cs.Manufacturer
        Model = $cs.Model
        TotalPhysicalMemory = "{0:N2} GB" -f ($cs.TotalPhysicalMemory / 1GB)
    }
    $result | Format-List
    return $result
}

function Get-HardwareInventory {
    Write-Host "`nGathering Hardware Inventory..." -ForegroundColor Yellow
    $cpu = Get-CimInstance Win32_Processor
    $ram = Get-CimInstance Win32_PhysicalMemory
    $disk = Get-CimInstance Win32_DiskDrive
    $gpu = Get-CimInstance Win32_VideoController

    $result = [PSCustomObject]@{
        CPU = "$($cpu.Name) ($($cpu.NumberOfCores) cores, $($cpu.NumberOfLogicalProcessors) logical processors)"
        RAM = $ram | ForEach-Object { "$($_.Capacity / 1GB) GB $($_.Manufacturer)" }
        Disks = $disk | ForEach-Object { "$($_.Model) ($([math]::Round($_.Size / 1GB)) GB)" }
        GPU = $gpu.Name
    }
    $result | Format-List
    return $result
}

function Get-InstalledSoftware {
    Write-Host "`nGathering Installed Software..." -ForegroundColor Yellow
    $software = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*,
                                 HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
                Where-Object { $_.DisplayName -and $_.DisplayName -notmatch '^(Update for|Security Update for|Hotfix for)' } |
                Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
                Sort-Object DisplayName

    $software | Format-Table -AutoSize
    return $software
}

function Get-WindowsUpdateStatus {
    Write-Host "`nChecking Windows Update Status..." -ForegroundColor Yellow
    $updateSession = New-Object -ComObject Microsoft.Update.Session
    $updateSearcher = $updateSession.CreateUpdateSearcher()
    $pendingUpdates = $updateSearcher.Search("IsInstalled=0")

    $lastUpdate = Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 1

    $result = [PSCustomObject]@{
        PendingUpdatesCount = $pendingUpdates.Updates.Count
        LastUpdateDate = $lastUpdate.InstalledOn
        LastUpdateHotfixID = $lastUpdate.HotFixID
    }
    $result | Format-List
    return $result
}

function Get-SecuritySettings {
    Write-Host "`nGathering Security Settings..." -ForegroundColor Yellow
    $firewall = Get-NetFirewallProfile
    $av = Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct
    $uac = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA"

    $result = [PSCustomObject]@{
        FirewallStatus = $firewall | ForEach-Object { "$($_.Name): $($_.Enabled)" }
        AntivirusProduct = $av.displayName
        UACEnabled = if ($uac.EnableLUA -eq 1) { "Enabled" } else { "Disabled" }
    }
    $result | Format-List
    return $result
}

function Get-NetworkConfiguration {
    Write-Host "`nGathering Network Configuration..." -ForegroundColor Yellow
    $adapters = Get-NetAdapter | Where-Object { $_.Status -eq "Up" }
    $result = @()
    foreach ($adapter in $adapters) {
        $ipConfig = Get-NetIPConfiguration -InterfaceIndex $adapter.ifIndex
        $result += [PSCustomObject]@{
            InterfaceName = $adapter.Name
            InterfaceDescription = $adapter.InterfaceDescription
            MACAddress = $adapter.MacAddress
            IPAddress = $ipConfig.IPv4Address.IPAddress
            SubnetMask = $ipConfig.IPv4Address.PrefixLength
            DefaultGateway = $ipConfig.IPv4DefaultGateway.NextHop
            DNSServers = $ipConfig.DNSServer.ServerAddresses -join ", "
        }
    }
    $result | Format-Table -AutoSize
    return $result
}

function Get-UserAccountsAndGroups {
    Write-Host "`nGathering User Accounts and Groups..." -ForegroundColor Yellow
    $users = Get-LocalUser | Select-Object Name, Enabled, LastLogon, PasswordLastSet
    $groups = Get-LocalGroup | Select-Object Name, Description

    $result = [PSCustomObject]@{
        Users = $users
        Groups = $groups
    }
    $result.Users | Format-Table -AutoSize
    $result.Groups | Format-Table -AutoSize
    return $result
}

function Get-StartupPrograms {
    Write-Host "`nGathering Startup Programs..." -ForegroundColor Yellow
    $startupPrograms = Get-CimInstance Win32_StartupCommand | Select-Object Name, Command, Location, User
    $startupPrograms | Format-Table -AutoSize
    return $startupPrograms
}

function Get-DiskSpaceAndFileSystem {
    Write-Host "`nAnalyzing Disk Space and File System..." -ForegroundColor Yellow
    $disks = Get-CimInstance Win32_LogicalDisk | Where-Object { $_.DriveType -eq 3 }
    $result = @()
    foreach ($disk in $disks) {
        $result += [PSCustomObject]@{
            DriveLetter = $disk.DeviceID
            VolumeName = $disk.VolumeName
            FileSystem = $disk.FileSystem
            TotalSpace = "{0:N2} GB" -f ($disk.Size / 1GB)
            FreeSpace = "{0:N2} GB" -f ($disk.FreeSpace / 1GB)
            PercentFree = "{0:N2}%" -f (($disk.FreeSpace / $disk.Size) * 100)
        }
    }
    $result | Format-Table -AutoSize
    return $result
}

function Get-EventLogAnalysis {
    Write-Host "`nAnalyzing Event Logs..." -ForegroundColor Yellow
    $logs = @("System", "Application", "Security")
    $result = @()
    foreach ($log in $logs) {
        $events = Get-EventLog -LogName $log -Newest 100
        $errorCount = ($events | Where-Object { $_.EntryType -eq "Error" }).Count
        $warningCount = ($events | Where-Object { $_.EntryType -eq "Warning" }).Count
        $result += [PSCustomObject]@{
            LogName = $log
            TotalEvents = $events.Count
            ErrorCount = $errorCount
            WarningCount = $warningCount
            MostCommonSource = ($events | Group-Object Source | Sort-Object Count -Descending | Select-Object -First 1).Name
        }
    }
    $result | Format-Table -AutoSize
    return $result
}

function Generate-HTMLReport {
    param([hashtable]$AllResults)

    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Windows Client Audit Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .warning { color: orange; }
        .critical { color: red; }
    </style>
</head>
<body>
    <h1>Windows Client Audit Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>System Information</h2>
    $($AllResults.SystemInfo | ConvertTo-Html -Fragment)

    <h2>Hardware Inventory</h2>
    $($AllResults.HardwareInventory | ConvertTo-Html -Fragment)

    <h2>Installed Software</h2>
    $($AllResults.InstalledSoftware | ConvertTo-Html -Fragment)

    <h2>Windows Update Status</h2>
    $($AllResults.WindowsUpdateStatus | ConvertTo-Html -Fragment)

    <h2>Security Settings</h2>
    $($AllResults.SecuritySettings | ConvertTo-Html -Fragment)

    <h2>Network Configuration</h2>
    $($AllResults.NetworkConfig | ConvertTo-Html -Fragment)

    <h2>User Accounts and Groups</h2>
    <h3>Users</h3>
    $($AllResults.UserAccountsAndGroups.Users | ConvertTo-Html -Fragment)
    <h3>Groups</h3>
    $($AllResults.UserAccountsAndGroups.Groups | ConvertTo-Html -Fragment)

    <h2>Startup Programs</h2>
    $($AllResults.StartupPrograms | ConvertTo-Html -Fragment)

    <h2>Disk Space and File System</h2>
    $($AllResults.DiskSpace | ConvertTo-Html -Fragment)

    <h2>Event Log Analysis</h2>
    $($AllResults.EventLogAnalysis | ConvertTo-Html -Fragment)
</body>
</html>
"@

    $reportContent | Out-File -FilePath $global:reportPath
    Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green
}

# Main program loop
$allResults = @{}

do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-12)"

    switch ($choice) {
        "1" { $allResults.SystemInfo = Get-SystemInformation }
        "2" { $allResults.HardwareInventory = Get-HardwareInventory }
        "3" { $allResults.InstalledSoftware = Get-InstalledSoftware }
        "4" { $allResults.WindowsUpdateStatus = Get-WindowsUpdateStatus }
        "5" { $allResults.SecuritySettings = Get-SecuritySettings }
        "6" { $allResults.NetworkConfig = Get-NetworkConfiguration }
        "7" { $allResults.UserAccountsAndGroups = Get-UserAccountsAndGroups }
        "8" { $allResults.StartupPrograms = Get-StartupPrograms }
        "9" { $allResults.DiskSpace = Get-DiskSpaceAndFileSystem }
        "10" { $allResults.EventLogAnalysis = Get-EventLogAnalysis }
        "11" { Generate-HTMLReport -AllResults $allResults }
        "12" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "12") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "12")

This Local Windows Client Audit Toolkit includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to gather various aspects of system information:
    • System Information (OS details, manufacturer, model, etc.)
    • Hardware Inventory (CPU, RAM, disk, GPU)
    • Installed Software
    • Windows Update Status
    • Security Settings (firewall, antivirus, UAC)
    • Network Configuration
    • User Accounts and Groups
    • Startup Programs
    • Disk Space and File System information
    • Event Log Analysis
  3. HTML report generation for easy sharing and viewing of results

Key features:

  • Comprehensive system information gathering
  • Detailed hardware inventory
  • Software inventory including version information
  • Windows update status check
  • Security settings overview
  • Network configuration details
  • User account and group information
  • Startup program listing
  • Disk space analysis
  • Basic event log analysis

This tool is particularly useful for:

  • IT administrators performing system audits
  • Help desk personnel gathering system information
  • System analysts investigating performance or security issues
  • Anyone needing a comprehensive overview of a Windows client machine

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query system information
  3. Review the generated HTML report for a comprehensive overview of the system

This script provides a thorough audit of a Windows client machine, making it easier to inventory, troubleshoot, or document system configurations. Remember to use this tool responsibly and respect privacy and security policies when auditing systems.

Windows Services Analyzer Tool

<#
.SYNOPSIS
Windows Services Analyzer Tool

.DESCRIPTION
This script analyzes and audits Windows services on local or remote systems,
providing insights into service configurations, startup types, and potential issues.

.NOTES
File Name      : ServicesAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, administrator rights
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\ServicesAnalyzer.ps1
#>

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\Services_Analysis_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
$global:targetComputer = $env:COMPUTERNAME

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Windows Services Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "Current Target: $global:targetComputer"
    Write-Host "1. Set Target Computer"
    Write-Host "2. Analyze All Services"
    Write-Host "3. Check Automatic Services Not Running"
    Write-Host "4. Identify Manual Services Running"
    Write-Host "5. Analyze Service Dependencies"
    Write-Host "6. Check Services with Non-Standard Accounts"
    Write-Host "7. Identify Services with No Description"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Sets the target computer for analysis.
#>
function Set-TargetComputer {
    $computer = Read-Host "Enter the name of the target computer (or press Enter for local machine)"
    if ([string]::IsNullOrWhiteSpace($computer)) {
        $global:targetComputer = $env:COMPUTERNAME
    } else {
        $global:targetComputer = $computer
    }
    Write-Host "Target computer set to: $global:targetComputer" -ForegroundColor Green
}

<#
.SYNOPSIS
Analyzes all services on the target computer.

.OUTPUTS
Array of PSObjects containing service details.
#>
function Analyze-AllServices {
    Write-Host "`nAnalyzing All Services..." -ForegroundColor Yellow
    try {
        $services = Get-WmiObject -Class Win32_Service -ComputerName $global:targetComputer
        $results = @()
        foreach ($service in $services) {
            $results += [PSCustomObject]@{
                Name = $service.Name
                DisplayName = $service.DisplayName
                State = $service.State
                StartMode = $service.StartMode
                StartName = $service.StartName
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error analyzing services: $_" -ForegroundColor Red
        return $null
    }
}

<#
.SYNOPSIS
Checks for automatic services that are not running.

.OUTPUTS
Array of PSObjects containing details of automatic services not running.
#>
function Check-AutomaticServicesNotRunning {
    Write-Host "`nChecking Automatic Services Not Running..." -ForegroundColor Yellow
    try {
        $services = Get-WmiObject -Class Win32_Service -ComputerName $global:targetComputer |
                    Where-Object { $_.StartMode -eq "Auto" -and $_.State -ne "Running" }
        $results = @()
        foreach ($service in $services) {
            $results += [PSCustomObject]@{
                Name = $service.Name
                DisplayName = $service.DisplayName
                State = $service.State
                StartMode = $service.StartMode
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error checking automatic services: $_" -ForegroundColor Red
        return $null
    }
}

<#
.SYNOPSIS
Identifies manual services that are running.

.OUTPUTS
Array of PSObjects containing details of manual services running.
#>
function Identify-ManualServicesRunning {
    Write-Host "`nIdentifying Manual Services Running..." -ForegroundColor Yellow
    try {
        $services = Get-WmiObject -Class Win32_Service -ComputerName $global:targetComputer |
                    Where-Object { $_.StartMode -eq "Manual" -and $_.State -eq "Running" }
        $results = @()
        foreach ($service in $services) {
            $results += [PSCustomObject]@{
                Name = $service.Name
                DisplayName = $service.DisplayName
                State = $service.State
                StartMode = $service.StartMode
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error identifying manual services: $_" -ForegroundColor Red
        return $null
    }
}

<#
.SYNOPSIS
Analyzes service dependencies.

.OUTPUTS
Array of PSObjects containing service dependency details.
#>
function Analyze-ServiceDependencies {
    Write-Host "`nAnalyzing Service Dependencies..." -ForegroundColor Yellow
    try {
        $services = Get-WmiObject -Class Win32_Service -ComputerName $global:targetComputer
        $results = @()
        foreach ($service in $services) {
            if ($service.DependentServices) {
                $results += [PSCustomObject]@{
                    Name = $service.Name
                    DisplayName = $service.DisplayName
                    DependentServices = $service.DependentServices -join ", "
                }
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error analyzing service dependencies: $_" -ForegroundColor Red
        return $null
    }
}

<#
.SYNOPSIS
Checks for services with non-standard accounts.

.OUTPUTS
Array of PSObjects containing details of services with non-standard accounts.
#>
function Check-ServicesWithNonStandardAccounts {
    Write-Host "`nChecking Services with Non-Standard Accounts..." -ForegroundColor Yellow
    try {
        $standardAccounts = @("LocalSystem", "NT AUTHORITY\LocalService", "NT AUTHORITY\NetworkService")
        $services = Get-WmiObject -Class Win32_Service -ComputerName $global:targetComputer |
                    Where-Object { $standardAccounts -notcontains $_.StartName }
        $results = @()
        foreach ($service in $services) {
            $results += [PSCustomObject]@{
                Name = $service.Name
                DisplayName = $service.DisplayName
                StartName = $service.StartName
                State = $service.State
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error checking services with non-standard accounts: $_" -ForegroundColor Red
        return $null
    }
}

<#
.SYNOPSIS
Identifies services with no description.

.OUTPUTS
Array of PSObjects containing details of services with no description.
#>
function Identify-ServicesWithNoDescription {
    Write-Host "`nIdentifying Services with No Description..." -ForegroundColor Yellow
    try {
        $services = Get-WmiObject -Class Win32_Service -ComputerName $global:targetComputer |
                    Where-Object { [string]::IsNullOrWhiteSpace($_.Description) }
        $results = @()
        foreach ($service in $services) {
            $results += [PSCustomObject]@{
                Name = $service.Name
                DisplayName = $service.DisplayName
                State = $service.State
                StartMode = $service.StartMode
            }
        }
        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error identifying services with no description: $_" -ForegroundColor Red
        return $null
    }
}

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Windows Services Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
    </style>
</head>
<body>
    <h1>Windows Services Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>
    <p>Target Computer: $global:targetComputer</p>

    <h2>All Services</h2>
    $($AllResults.AllServices | ConvertTo-Html -Fragment)

    <h2>Automatic Services Not Running</h2>
    $($AllResults.AutomaticNotRunning | ConvertTo-Html -Fragment)

    <h2>Manual Services Running</h2>
    $($AllResults.ManualRunning | ConvertTo-Html -Fragment)

    <h2>Service Dependencies</h2>
    $($AllResults.ServiceDependencies | ConvertTo-Html -Fragment)

    <h2>Services with Non-Standard Accounts</h2>
    $($AllResults.NonStandardAccounts | ConvertTo-Html -Fragment)

    <h2>Services with No Description</h2>
    $($AllResults.NoDescription | ConvertTo-Html -Fragment)
</body>
</html>
"@

    $reportContent | Out-File -FilePath $global:reportPath
    Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green
}

# Main program loop
$allResults = @{}

do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-9)"

    switch ($choice) {
        "1" { Set-TargetComputer }
        "2" { $allResults.AllServices = Analyze-AllServices }
        "3" { $allResults.AutomaticNotRunning = Check-AutomaticServicesNotRunning }
        "4" { $allResults.ManualRunning = Identify-ManualServicesRunning }
        "5" { $allResults.ServiceDependencies = Analyze-ServiceDependencies }
        "6" { $allResults.NonStandardAccounts = Check-ServicesWithNonStandardAccounts }
        "7" { $allResults.NoDescription = Identify-ServicesWithNoDescription }
        "8" { Generate-HTMLReport -AllResults $allResults }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "9") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "9")

This Windows Services Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of Windows services:
    • Analysis of all services
    • Check for automatic services not running
    • Identification of manual services running
    • Analysis of service dependencies
    • Check for services with non-standard accounts
    • Identification of services with no description
  3. Ability to set a target computer for remote analysis.
  4. Comprehensive error handling for each analysis function.
  5. A function to generate an HTML report of all collected data.

Key features:

  • Detailed analysis of all services on the target system
  • Identification of potential issues like automatic services not running
  • Detection of manual services that are running (which might be unnecessary)
  • Analysis of service dependencies to understand the impact of service failures
  • Identification of services using non-standard accounts (potential security concern)
  • Detection of services lacking descriptions (which might indicate unauthorized or suspicious services)
  • Comprehensive HTML report generation

This tool is particularly useful for:

  • System administrators managing Windows services
  • Security professionals auditing service configurations
  • IT professionals troubleshooting service-related issues
  • Compliance officers ensuring proper service configurations

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query services on the target computer
  3. Be cautious when analyzing services on production systems

This script provides a comprehensive overview of Windows services, making it easier to audit and maintain proper service configurations, identify potential security issues, and ensure the correct setup of services across Windows systems.

RDS Login and Logout Logging Script

<#
.SYNOPSIS
RDS Login and Logout Logging Script

.DESCRIPTION
This script automatically logs user login and logout events for Remote Desktop Services.
It runs continuously as a background job, monitoring the Windows Event Log for relevant events.

.NOTES
File Name      : RDSLoginLogoutLogger.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V3 or later, admin rights on the RDS server
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
Start-Job -FilePath .\RDSLoginLogoutLogger.ps1
#>

# Configuration
$logFilePath = "C:\Logs\RDSLoginLogout.log"
$lastRunFile = "C:\Logs\RDSLoginLogoutLastRun.txt"

# Ensure log directory exists
$logDir = Split-Path $logFilePath -Parent
if (-not (Test-Path $logDir)) {
    New-Item -ItemType Directory -Path $logDir | Out-Null
}

# Function to write log entries
function Write-Log {
    param (
        [string]$Message
    )
    
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logEntry = "$timestamp - $Message"
    Add-Content -Path $logFilePath -Value $logEntry
}

# Function to get the last run time
function Get-LastRunTime {
    if (Test-Path $lastRunFile) {
        return Get-Content $lastRunFile
    }
    return (Get-Date).AddDays(-1).ToString("o")  # Default to 1 day ago if no last run time
}

# Function to save the last run time
function Save-LastRunTime {
    param (
        [DateTime]$LastRunTime
    )
    $LastRunTime.ToString("o") | Set-Content $lastRunFile
}

# Main logging loop
try {
    Write-Log "RDS Login/Logout logging started."

    while ($true) {
        $lastRunTime = Get-LastRunTime
        $currentTime = Get-Date

        # Query for login events
        $loginEvents = Get-WinEvent -FilterHashtable @{
            LogName = 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'
            ID = 21  # Event ID for session logon
            StartTime = $lastRunTime
        } -ErrorAction SilentlyContinue

        # Query for logout events
        $logoutEvents = Get-WinEvent -FilterHashtable @{
            LogName = 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'
            ID = 23  # Event ID for session logoff
            StartTime = $lastRunTime
        } -ErrorAction SilentlyContinue

        # Process login events
        foreach ($event in $loginEvents) {
            $username = $event.Properties[0].Value
            $sessionId = $event.Properties[1].Value
            Write-Log "User logged in: $username (Session ID: $sessionId)"
        }

        # Process logout events
        foreach ($event in $logoutEvents) {
            $username = $event.Properties[0].Value
            $sessionId = $event.Properties[1].Value
            Write-Log "User logged out: $username (Session ID: $sessionId)"
        }

        # Save the current time as the last run time
        Save-LastRunTime $currentTime

        # Wait for a minute before the next check
        Start-Sleep -Seconds 60
    }
}
catch {
    Write-Log "An error occurred: $_"
}
finally {
    Write-Log "RDS Login/Logout logging stopped."
}

To use this script:

  1. Save the script as RDSLoginLogoutLogger.ps1 in a suitable location on your RDS server.
  2. Modify the $logFilePath and $lastRunFile variables at the beginning of the script if you want to change the default log locations.
  3. To run the script as a background job, open PowerShell as an administrator and use the following command:
    Start-Job -FilePath C:\Path\To\RDSLoginLogoutLogger.ps1
    Replace C:\Path\To\ with the actual path where you saved the script.
  4. To check the status of the job: Get-Job
  5. To stop the job when needed: Stop-Job -Id <JobId>
  6. Replace <JobId> with the ID of the job from the Get-Job command.

Key features of this script:

  1. Continuous Monitoring: Runs as a background job, continuously checking for new login and logout events.
  2. Efficient Event Querying: Uses the last run time to query only for new events since the last check.
  3. Separate Log File: Logs events to a dedicated file for easy review and analysis.
  4. Error Handling: Includes basic error handling to log any issues that occur during execution.
  5. Low Resource Usage: Checks for new events every minute, balancing timeliness with system resource usage.

Notes:

  • This script needs to be run with administrator privileges on the RDS server.
  • The script creates a log file and a last run time file. Ensure the specified paths are accessible and writable.
  • For long-term use, consider implementing a log rotation mechanism to manage log file sizes.
  • You may need to adjust the event IDs (21 for login, 23 for logout) if your RDS environment uses different event IDs for these actions.
  • Always test the script in a non-production environment before deploying it to production servers.

This script provides a robust solution for automatically logging RDS login and logout events, which can be valuable for security auditing, user activity tracking, and compliance purposes.

RDS Toolkit – Remote Desktop Services Management Script

<#
.SYNOPSIS
RDS Toolkit - Comprehensive Remote Desktop Services Management Script

.DESCRIPTION
This script provides a set of tools for managing and monitoring Remote Desktop Services environments.
It includes functions for session management, user monitoring, performance analysis, and reporting.

.NOTES
File Name      : RDSToolkit.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, admin rights on the RDS server
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\RDSToolkit.ps1
#>

# Import required modules
Import-Module RemoteDesktop

# Global variables
$global:logFile = "$env:USERPROFILE\Desktop\RDS_Toolkit_Log_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"

function Write-Log {
    param (
        [string]$Message
    )
    
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logEntry = "$timestamp - $Message"
    Add-Content -Path $global:logFile -Value $logEntry
    Write-Host $logEntry
}

function Show-Menu {
    Clear-Host
    Write-Host "=== RDS Toolkit ===" -ForegroundColor Cyan
    Write-Host "1. List Active Sessions"
    Write-Host "2. Disconnect User"
    Write-Host "3. Log Off User"
    Write-Host "4. Send Message to Users"
    Write-Host "5. Monitor Disconnected Sessions"
    Write-Host "6. View RDS Server Performance"
    Write-Host "7. Generate RDS Usage Report"
    Write-Host "8. Manage RDS Collections"
    Write-Host "9. Exit"
}

function Get-ActiveSessions {
    $sessions = quser | Where-Object { $_ -match 'Active' }
    $activeSessions = @()
    foreach ($session in $sessions) {
        $sessionInfo = $session -split '\s+'
        $activeSessions += [PSCustomObject]@{
            Username = $sessionInfo[1]
            SessionID = $sessionInfo[2]
            State = $sessionInfo[3]
            IdleTime = $sessionInfo[4]
            LogonTime = $sessionInfo[5..($sessionInfo.Length-1)] -join ' '
        }
    }
    return $activeSessions
}

function Disconnect-RDSUser {
    $username = Read-Host "Enter username to disconnect"
    $sessions = quser | Where-Object { $_ -match $username }
    if ($sessions) {
        $sessionId = ($sessions -split '\s+')[2]
        tsdiscon $sessionId
        Write-Log "Disconnected user: $username (Session ID: $sessionId)"
    } else {
        Write-Host "User not found or not connected." -ForegroundColor Yellow
    }
}

function LogOff-RDSUser {
    $username = Read-Host "Enter username to log off"
    $sessions = quser | Where-Object { $_ -match $username }
    if ($sessions) {
        $sessionId = ($sessions -split '\s+')[2]
        logoff $sessionId
        Write-Log "Logged off user: $username (Session ID: $sessionId)"
    } else {
        Write-Host "User not found or not connected." -ForegroundColor Yellow
    }
}

function Send-MessageToUsers {
    $message = Read-Host "Enter message to send"
    $users = Get-ActiveSessions
    foreach ($user in $users) {
        msg $user.Username $message
    }
    Write-Log "Sent message to all active users: $message"
}

function Monitor-DisconnectedSessions {
    $duration = Read-Host "Enter monitoring duration in minutes (0 for continuous)"
    $startTime = Get-Date
    Write-Host "Monitoring disconnected sessions. Press Ctrl+C to stop." -ForegroundColor Yellow
    
    try {
        while ($true) {
            $disconnectedSessions = quser | Where-Object { $_ -match 'Disc' }
            foreach ($session in $disconnectedSessions) {
                $sessionInfo = $session -split '\s+'
                Write-Host "Disconnected: $($sessionInfo[1]) (Session ID: $($sessionInfo[2]))" -ForegroundColor Red
                Write-Log "Disconnected session detected: $($sessionInfo[1]) (Session ID: $($sessionInfo[2]))"
            }
            
            if ($duration -ne "0" -and ((Get-Date) - $startTime).TotalMinutes -ge $duration) {
                break
            }
            
            Start-Sleep -Seconds 30
        }
    }
    catch {
        Write-Host "Monitoring stopped." -ForegroundColor Yellow
    }
}

function View-RDSServerPerformance {
    $duration = Read-Host "Enter monitoring duration in minutes"
    $interval = Read-Host "Enter sampling interval in seconds"
    $startTime = Get-Date
    $endTime = $startTime.AddMinutes($duration)
    
    Write-Host "Monitoring RDS server performance. This may take $duration minutes." -ForegroundColor Yellow
    
    $performanceData = @()
    
    while ((Get-Date) -lt $endTime) {
        $cpu = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue
        $memory = (Get-Counter '\Memory\% Committed Bytes In Use').CounterSamples.CookedValue
        $disk = (Get-Counter '\PhysicalDisk(_Total)\% Disk Time').CounterSamples.CookedValue
        $network = (Get-Counter '\Network Interface(*)\Bytes Total/sec').CounterSamples.CookedValue | Measure-Object -Sum | Select-Object -ExpandProperty Sum
        
        $performanceData += [PSCustomObject]@{
            Timestamp = Get-Date
            CPU = [math]::Round($cpu, 2)
            Memory = [math]::Round($memory, 2)
            Disk = [math]::Round($disk, 2)
            Network = [math]::Round($network / 1MB, 2)  # Convert to MB/s
        }
        
        Start-Sleep -Seconds $interval
    }
    
    $performanceData | Format-Table -AutoSize
    $performanceData | Export-Csv -Path "$env:USERPROFILE\Desktop\RDS_Performance_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv" -NoTypeInformation
    Write-Host "Performance data exported to desktop." -ForegroundColor Green
}

function Generate-RDSUsageReport {
    $days = Read-Host "Enter number of days for the report"
    $startDate = (Get-Date).AddDays(-$days)
    $events = Get-WinEvent -FilterHashtable @{
        LogName = 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'
        ID = 21, 23, 24, 25  # Logon, Logoff, Disconnect, Reconnect
        StartTime = $startDate
    }
    
    $report = @()
    foreach ($event in $events) {
        $report += [PSCustomObject]@{
            Timestamp = $event.TimeCreated
            Username = $event.Properties[0].Value
            EventType = switch ($event.Id) {
                21 { "Logon" }
                23 { "Logoff" }
                24 { "Disconnect" }
                25 { "Reconnect" }
            }
        }
    }
    
    $report | Format-Table -AutoSize
    $report | Export-Csv -Path "$env:USERPROFILE\Desktop\RDS_Usage_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv" -NoTypeInformation
    Write-Host "Usage report exported to desktop." -ForegroundColor Green
}

function Manage-RDSCollections {
    Write-Host "RDS Collections Management" -ForegroundColor Cyan
    Write-Host "1. List Collections"
    Write-Host "2. Create New Collection"
    Write-Host "3. Add Server to Collection"
    Write-Host "4. Remove Server from Collection"
    Write-Host "5. Back to Main Menu"
    
    $choice = Read-Host "Enter your choice"
    
    switch ($choice) {
        "1" {
            Get-RDSessionCollection | Format-Table -AutoSize
        }
        "2" {
            $name = Read-Host "Enter new collection name"
            $sessionHost = Read-Host "Enter session host server name"
            New-RDSessionCollection -CollectionName $name -SessionHost $sessionHost
            Write-Log "Created new RDS collection: $name"
        }
        "3" {
            $collection = Read-Host "Enter collection name"
            $server = Read-Host "Enter server to add"
            Add-RDSessionHost -CollectionName $collection -SessionHost $server
            Write-Log "Added server $server to collection $collection"
        }
        "4" {
            $collection = Read-Host "Enter collection name"
            $server = Read-Host "Enter server to remove"
            Remove-RDSessionHost -CollectionName $collection -SessionHost $server
            Write-Log "Removed server $server from collection $collection"
        }
        "5" {
            return
        }
        default {
            Write-Host "Invalid choice. Please try again." -ForegroundColor Red
        }
    }
    
    Pause
    Manage-RDSCollections
}

# Main program loop
do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-9)"

    switch ($choice) {
        "1" { Get-ActiveSessions | Format-Table -AutoSize }
        "2" { Disconnect-RDSUser }
        "3" { LogOff-RDSUser }
        "4" { Send-MessageToUsers }
        "5" { Monitor-DisconnectedSessions }
        "6" { View-RDSServerPerformance }
        "7" { Generate-RDSUsageReport }
        "8" { Manage-RDSCollections }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "9") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "9")

This RDS Toolkit script provides a comprehensive set of tools for managing and monitoring Remote Desktop Services environments. Here’s a breakdown of its features:

  1. List Active Sessions: Displays all currently active RDS sessions.
  2. Disconnect User: Allows you to disconnect a specific user.
  3. Log Off User: Allows you to log off a specific user.
  4. Send Message to Users: Sends a broadcast message to all active users.
  5. Monitor Disconnected Sessions: Continuously monitors and reports on disconnected sessions.
  6. View RDS Server Performance: Monitors and reports on server performance metrics (CPU, Memory, Disk, Network).
  7. Generate RDS Usage Report: Creates a report of RDS usage over a specified number of days.
  8. Manage RDS Collections: Provides options to list, create, and modify RDS collections.

To use this script:

  1. Save it as RDSToolkit.ps1.
  2. Open PowerShell as an administrator on the RDS server.
  3. Navigate to the directory containing the script.
  4. Run the script:

.\RDSToolkit.ps1

Notes:

  • This script requires administrative privileges on the RDS server.
  • Some functions may require additional modules or permissions depending on your RDS setup.
  • The script creates log files and exports reports to the desktop by default. You may want to modify these paths for production use.
  • Always test the script in a non-production environment before using it in production.

This toolkit provides a solid foundation for managing RDS environments and can be further customized based on specific organizational needs or more complex RDS setups.