mqsft.windowsserveradmin.psm1

# ==============================================================================
# mqsft.windowsserveradmin.psm1 - AUTO-GENERATED by Create_Module_0_0_7.ps1 v0.0.7
# ------------------------------------------------------------------------------
# Module Version : 1.0.4
# Script Version : 0.0.7
# Built : 2026-02-25 10:47:39
# Source : C:\Modules\functions\mqsft.windowsserveradmin
#
# DO NOT EDIT THIS FILE DIRECTLY.
# Edit source files in C:\Modules\functions\mqsft.windowsserveradmin and re-run Create_Module_0_0_7.ps1.
# ==============================================================================

Set-StrictMode -Version Latest

# --- Source: Get-FSMORoles.ps1 -------------------------------------------
function Get-FSMORoles {

Param

(

    [Parameter(Mandatory = $true)] $Domain

)  

Import-Module activedirectory

[array]$OutputArray=@()

$ADforestRoles = Get-ADForest $Domain

$ADDomainRoles = Get-ADDomain $Domain

$OutputArray+=(New-Object PSCustomObject -Property `

@{"DomainNamingMaster"=$ADforestRoles.DomainNamingMaster;"SchemaMaster"=$ADforestRoles.SchemaMaster;

"InfrastructureMaster"=$ADdomainRoles.InfrastructureMaster;"PDCEmulator"=$ADdomainRoles.PDCEmulator;

"RIDMaster"=$ADdomainRoles.RIDMaster;})

$OutputArray

}



Get-FSMORoles -domain "asos.local"





Get - FSMORoles - Updated



function Get-FSMORoles {

    Param(

        [Parameter(Mandatory = $true)]

        [string]$Domain

    )  

    

    Import-Module ActiveDirectory

    

    [array]$OutputArray = @()

    $ADForestRoles = Get-ADForest $Domain

    $ADDomainRoles = Get-ADDomain $Domain

    

    $OutputArray += (New-Object PSCustomObject -Property @{

        "DomainNamingMaster" = $ADForestRoles.DomainNamingMaster

        "SchemaMaster" = $ADForestRoles.SchemaMaster

        "InfrastructureMaster" = $ADDomainRoles.InfrastructureMaster

        "PDCEmulator" = $ADDomainRoles.PDCEmulator

        "RIDMaster" = $ADDomainRoles.RIDMaster

    })

    

    return $OutputArray

}
# --- Source: Get-LocalAdministrators.ps1 ---------------------------------
function Get-LocalAdministrators {

    <#

    .SYNOPSIS

        Retrieves members of the local Administrators group with detailed information.

    

    .DESCRIPTION

        Enumerates all members of the local Administrators group including users, domain users,

        groups, and orphaned SIDs. Provides flexible output formats for different use cases.

    

    .PARAMETER OutputFormat

        Format for displaying results. Options: Table, List, Grid, CSV, JSON, Object

        Default is Table.

    

    .PARAMETER ExportPath

        Path to export results. File extension determines format (.csv or .json)

    

    .PARAMETER IncludeOrphaned

        Include orphaned SIDs in the output. Default is $true.

    

    .PARAMETER ComputerName

        Remote computer name to query. Default is local computer.

    

    .EXAMPLE

        Get-LocalAdministrators

        

    .EXAMPLE

        Get-LocalAdministrators -OutputFormat List

        

    .EXAMPLE

        Get-LocalAdministrators -ExportPath "C:\admins.csv"

        

    .EXAMPLE

        Get-LocalAdministrators -OutputFormat JSON -ExportPath "C:\admins.json"

        

    .EXAMPLE

        $admins = Get-LocalAdministrators -OutputFormat Object

        $admins | Where-Object {$_.Status -eq "Orphaned SID"}

    #>


    

    [CmdletBinding()]

    param(

        [Parameter(Mandatory=$false)]

        [ValidateSet('Table', 'List', 'Grid', 'CSV', 'JSON', 'Object')]

        [string]$OutputFormat = 'Table',

        

        [Parameter(Mandatory=$false)]

        [string]$ExportPath,

        

        [Parameter(Mandatory=$false)]

        [bool]$IncludeOrphaned = $true,

        

        [Parameter(Mandatory=$false)]

        [string]$ComputerName = "."

    )

    

    Write-Host "`nRetrieving local administrator group members..." -ForegroundColor Cyan

    

    try {

        # Connect to the Administrators group

        $adminGroup = [ADSI]"WinNT://$ComputerName/Administrators,group"

        $members = $adminGroup.Invoke("Members")

        

        $results = @()

        $count = 0

        

        foreach ($member in $members) {

            $count++

            Write-Progress -Activity "Processing Administrator Members" -Status "Member $count" -PercentComplete (($count / @($members).Count) * 100)

            

            try {

                # Get the ADsPath first

                $adsPath = $member.GetType().InvokeMember("ADsPath", 'GetProperty', $null, $member, $null)

                

                # Create ADSI object from the path

                $user = [ADSI]$adsPath

                

                # Try to get properties using InvokeMember

                $userName = $member.GetType().InvokeMember("Name", 'GetProperty', $null, $member, $null)

                $userClass = $member.GetType().InvokeMember("Class", 'GetProperty', $null, $member, $null)

                

                # Try to get SID

                $sidValue = "Unable to retrieve SID"

                try {

                    $objectSid = $member.GetType().InvokeMember("objectSid", 'GetProperty', $null, $member, $null)

                    if ($objectSid) {

                        $sid = New-Object System.Security.Principal.SecurityIdentifier($objectSid, 0)

                        $sidValue = $sid.Value

                    }

                } catch {

                    # SID retrieval failed, but we still have the name

                }

                

                # Determine account type

                $accountType = switch ($userClass) {

                    'User' { 'Local User' }

                    'Group' { 'Local Group' }

                    'ForeignSecurityPrincipal' { 'Domain Account' }

                    default { $userClass }

                }

                

                $results += [PSCustomObject]@{

                    Name        = $userName

                    AccountType = $accountType

                    Class       = $userClass

                    SID         = $sidValue

                    Status      = "Active"

                    Path        = $adsPath

                    ComputerName = $ComputerName

                }

                

            } catch {

                try {

                    # Fallback: try to get path and extract info

                    $path = $member.GetType().InvokeMember("ADsPath", 'GetProperty', $null, $member, $null)

                    

                    # Extract the last part of the path

                    $pathParts = $path -split '/'

                    $lastPart = $pathParts[-1]

                    

                    # Check if it's a SID format

                    if ($lastPart -match '^S-\d-\d+-(\d+-)*\d+$') {

                        try {

                            # Try to resolve the SID to a name

                            $sidObject = New-Object System.Security.Principal.SecurityIdentifier($lastPart)

                            $resolvedAccount = $sidObject.Translate([System.Security.Principal.NTAccount])

                            $resolvedName = $resolvedAccount.Value

                            

                            $results += [PSCustomObject]@{

                                Name        = $resolvedName

                                AccountType = "Resolved Account"

                                Class       = "Resolved"

                                SID         = $lastPart

                                Status      = "Resolved from SID"

                                Path        = $path

                                ComputerName = $ComputerName

                            }

                        } catch {

                            # Truly orphaned SID

                            if ($IncludeOrphaned) {

                                $results += [PSCustomObject]@{

                                    Name        = "Orphaned Account"

                                    AccountType = "Orphaned"

                                    Class       = "Orphaned"

                                    SID         = $lastPart

                                    Status      = "Orphaned SID"

                                    Path        = $path

                                    ComputerName = $ComputerName

                                }

                            }

                        }

                    } else {

                        # Try to extract name from the path or use the last part

                        $results += [PSCustomObject]@{

                            Name        = $lastPart

                            AccountType = "Unknown"

                            Class       = "Unknown"

                            SID         = "Unable to retrieve SID"

                            Status      = "Extracted from path"

                            Path        = $path

                            ComputerName = $ComputerName

                        }

                    }

                } catch {

                    $results += [PSCustomObject]@{

                        Name        = "Unable to process"

                        AccountType = "Error"

                        Class       = "Error"

                        SID         = "Unknown"

                        Status      = "Processing Error"

                        Path        = "Unknown"

                        ComputerName = $ComputerName

                    }

                }

            }

        }

        

        Write-Progress -Activity "Processing Administrator Members" -Completed

        

        # Summary statistics

        $totalCount = $results.Count

        $activeCount = ($results | Where-Object {$_.Status -eq "Active"}).Count

        $orphanedCount = ($results | Where-Object {$_.Status -eq "Orphaned SID"}).Count

        $domainCount = ($results | Where-Object {$_.AccountType -eq "Domain Account"}).Count

        $localUserCount = ($results | Where-Object {$_.AccountType -eq "Local User"}).Count

        $groupCount = ($results | Where-Object {$_.AccountType -like "*Group*"}).Count

        

        Write-Host "`nSummary:" -ForegroundColor Green

        Write-Host " Total Members: $totalCount"

        Write-Host " Active Accounts: $activeCount" -ForegroundColor Green

        Write-Host " Local Users: $localUserCount"

        Write-Host " Groups: $groupCount"

        Write-Host " Domain Accounts: $domainCount"

        if ($orphanedCount -gt 0) {

            Write-Host " Orphaned SIDs: $orphanedCount" -ForegroundColor Yellow

        }

        Write-Host ""

        

        # Handle export if specified

        if ($ExportPath) {

            $extension = [System.IO.Path]::GetExtension($ExportPath).ToLower()

            

            switch ($extension) {

                '.csv' {

                    $results | Export-Csv -Path $ExportPath -NoTypeInformation

                    Write-Host "Results exported to: $ExportPath" -ForegroundColor Cyan

                }

                '.json' {

                    $exportData = @{

                        Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"

                        ComputerName = $ComputerName

                        Summary = @{

                            TotalMembers = $totalCount

                            ActiveAccounts = $activeCount

                            OrphanedSIDs = $orphanedCount

                            DomainAccounts = $domainCount

                            LocalUsers = $localUserCount

                            Groups = $groupCount

                        }

                        Members = $results

                    }

                    $exportData | ConvertTo-Json -Depth 10 | Out-File -FilePath $ExportPath

                    Write-Host "Results exported to: $ExportPath" -ForegroundColor Cyan

                }

                default {

                    Write-Warning "Unsupported file extension. Using CSV format."

                    $results | Export-Csv -Path $ExportPath -NoTypeInformation

                    Write-Host "Results exported to: $ExportPath" -ForegroundColor Cyan

                }

            }

        }

        

        # Display results based on format

        switch ($OutputFormat) {

            'Table' {

                $results | Select-Object Name, AccountType, SID, Status | Format-Table -AutoSize

            }

            'List' {

                $results | Format-List Name, AccountType, Class, SID, Status, Path

            }

            'Grid' {

                $results | Out-GridView -Title "Local Administrators - $ComputerName"

            }

            'CSV' {

                $results | ConvertTo-Csv -NoTypeInformation | Write-Output

            }

            'JSON' {

                $results | ConvertTo-Json -Depth 10 | Write-Output

            }

            'Object' {

                return $results

            }

        }

        

        # Always return the object for pipeline usage

        if ($OutputFormat -ne 'Object') {

            return $results

        }

        

    } catch {

        Write-Error "Failed to retrieve administrator group members: $_"

        return $null

    }

}



# Example usage:

 Get-LocalAdministrators

# Get-LocalAdministrators -OutputFormat List

# Get-LocalAdministrators -OutputFormat Grid

# Get-LocalAdministrators -ExportPath "C:\admins.csv"

# Get-LocalAdministrators -OutputFormat JSON -ExportPath "C:\admins.json"

# $admins = Get-LocalAdministrators -OutputFormat Object

# $admins | Where-Object {$_.Status -eq "Orphaned SID"} | Format-Table
# --- Source: Get-Uptime.ps1 ----------------------------------------------
function Get-Uptime {

    <#

    .SYNOPSIS

        Gets the system uptime for the local machine.

    

    .DESCRIPTION

        Retrieves the system uptime by calculating the difference between the current time

        and the last boot time. Returns a formatted string or custom object.

    

    .PARAMETER Format

        Specifies the output format:

        - Simple: Returns a timespan object (default)

        - String: Returns formatted string like "5 days, 3 hours, 22 minutes"

        - Object: Returns a custom object with detailed properties

    

    .EXAMPLE

        Get-Uptime

        Returns: 5.03:22:15.1234567 (TimeSpan object)

    

    .EXAMPLE

        Get-Uptime -Format String

        Returns: "5 days, 3 hours, 22 minutes"

    

    .EXAMPLE

        Get-Uptime -Format Object

        Returns a custom object with ComputerName, LastBootTime, Days, Hours, Minutes, etc.

    #>


    

    [CmdletBinding()]

    param(

        [Parameter(Mandatory=$false)]

        [ValidateSet('Simple','String','Object')]

        [string]$Format = 'Simple'

    )

    

    try {

        # Get the operating system information

        $os = Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction Stop

        

        # Calculate uptime

        $uptime = (Get-Date) - $os.LastBootUpTime

        

        # Return based on format requested

        switch ($Format) {

            'Simple' {

                return $uptime

            }

            

            'String' {

                $days = if ($uptime.Days -eq 1) { "1 day" } else { "$($uptime.Days) days" }

                $hours = if ($uptime.Hours -eq 1) { "1 hour" } else { "$($uptime.Hours) hours" }

                $minutes = if ($uptime.Minutes -eq 1) { "1 minute" } else { "$($uptime.Minutes) minutes" }

                

                return "$days, $hours, $minutes"

            }

            

            'Object' {

                return [PSCustomObject]@{

                    ComputerName     = $env:COMPUTERNAME

                    LastBootTime     = $os.LastBootUpTime

                    CurrentTime      = Get-Date

                    Days             = $uptime.Days

                    Hours            = $uptime.Hours

                    Minutes          = $uptime.Minutes

                    Seconds          = $uptime.Seconds

                    TotalDays        = [math]::Round($uptime.TotalDays, 2)

                    TotalHours       = [math]::Round($uptime.TotalHours, 2)

                    TotalMinutes     = [math]::Round($uptime.TotalMinutes, 2)

                    FormattedUptime  = "$($uptime.Days)d $($uptime.Hours)h $($uptime.Minutes)m"

                }

            }

        }

    }

    catch {

        Write-Error "Failed to retrieve uptime: $_"

        return $null

    }

}



# Example usage:

# Get-Uptime

# Get-Uptime -Format String

# Get-Uptime -Format Object

# Get-Uptime -Format Object | Format-List
# --- Source: Set-TLS12.ps1 -----------------------------------------------
function Set-TLS12 {
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    Write-Host "TLS 1.2 set as security protocol." -ForegroundColor Green
}