Public/SCJBServerTeamTools.ps1

function SCJBServerTeamTools {
    <#
    .LINK
        https://www.powershellgallery.com/packages/SCJBServerTeamTools
    .EXAMPLE
        SCJBServerTeamTools
        Open to the home window
    .EXAMPLE
        SCJBServerTeamTools -QuickLaunch ADLookups
        Open to the ADLookups window
    .EXAMPLE
        SCJBServerTeamTools -QuickLaunch RSOP
        Open to the RSOP window
    .EXAMPLE
        STT -QuickLaunch SCCMDeployments
        Open using the alias to the SCCM deployments window
    .EXAMPLE
        STT -ShowSettings
        Outputs the tools settings file in a PS object.
    #>


    # MAIN TODO
    # - help window
    # - users - member of sccm collection (probably doesn't matter, we have like 10 user collections)
    # - _UpdateSCCMDevices use API instead
    # - SCCM Collection members
    # - datagrid header padding between columns
    # - hide first run output of LoganShell folder creation
    # - ComputerStats CPU round to 0 or 2 decimal places
    # - user tab - actions with a verify messagebox
    # - computer tab - install updates
    # - computer tab - schedule reboot
    # - computer tab - open in RDC mstsc /v:$ComputerName
    # - verify that the settingssaved variable works correctly
    # - add user or computer to a group with out-gridview
    # - use the $Session variable for stuff
    # - options - default domain and add that to _SaveSettings
    # - helper function that can be run to manually update the domain controller/ad domain without running STT
    # - adlookups - updating caches shows please wait while loading
    # - find tab - users search show name
    # - rsop - show text box to right for the text based gpresult that collapses
    # - smarter _SaveSettings so it doesn't overwrite existing credentials
    # - options prompt to save if something was changed.
    # - add performance monitors to computerstats
    # - netbox datagrid window
    # - RSOP - user not working
    # - add service startname to computerstats

    [CmdletBinding()]
    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Blackholes are fun.')]

    param (
        [Parameter(Mandatory = $false)]
        [ValidateSet('ADLookups', 'RSOP', 'SCCMDeployments', 'ComputerStats', 'Passphrases', 'WUG', 'CmdletHelp')]
        [string]
        $QuickLaunch,

        [Parameter(Mandatory = $false, HelpMessage = 'This will just output the contents of the settings file.')]
        [switch]
        $ShowSettings
    )

    # WPF framework
    Add-Type -AssemblyName PresentationFramework

    # Windows Form framework (message boxes)
    Add-Type -AssemblyName System.Windows.Forms
    # Add-Type -AssemblyName System.Drawing

    #region Pre-run checks and constants
    # Testing for the AD module manifest since workstations and servers use different methods to check the installation of RSAT tools and this seems faster.
    # TODO was still not working on SVM165 even with RSAT installed.
    # if (Test-Path 'C:\WINDOWS\System32\WindowsPowerShell\v1.0\Modules\ActiveDirectory\ActiveDirectory.psd1') {
    # Write-Warning 'RSAT AD Tools must be installed prior to use.'
    # break
    # }

    try {
        $Script:PDC = (Get-ADDomain).PDCEmulator
    }
    catch {
        Write-Warning 'Unable to contact a domain controller.'
        break
    }

    $Script:Module = Get-Module SCJBServerTeamTools
    $Script:ModuleName = 'SCJBServerTeamTools'

    #endregion

    #region First Run
    Write-Verbose 'Checking for first run'
    # TODO move this to it's own function with _InitialSettings
    if (!(Test-Path -Path $env:APPDATA\LoganShell\settings.json)) {
        # Settings file doesn't exist
        Write-Verbose 'First Run, creating directory and saving settings.'
        if (!(Test-Path -Path $env:APPDATA\LoganShell\)) {
            $Blackhole = New-Item -Path $env:APPDATA -Name 'LoganShell' -ItemType Directory
        }
        Write-Verbose 'Prompting for initial input'

        $userinput = Read-Host -Prompt 'Do you want to enable SCCM functionality? (Y/N)'
        switch ($userinput) {
            'Y' {
                $EnableSCCM = $true
                $SCCMServerInput = Read-Host -Prompt 'What is the hostname for the SCCM server?'
            }
            'N' {
                $EnableSCCM = $false
            }
            default {
                Write-Host 'Invalid option. Run again.'
                break
            }
        }

        $userinput = Read-Host -Prompt 'Do you want to enable Exchange on-premise functionality? (Y/N)'
        switch ($userinput) {
            'Y' {
                $EnableExchange = $true
            }
            'N' {
                $EnableExchange = $false
            }
            default {
                Write-Host 'Invalid option. Run again.'
                break
            }
        }

        Write-Verbose 'Setting temporary storage location'
        $ObjectFolder = 'C:\temp\Loganshell\'
        if (!(Test-Path $ObjectFolder)) {
            Write-Verbose 'Creating path.'
            New-Item -Path $ObjectFolder -ItemType Directory -Force -ErrorAction Stop
        }

        try {
            # Save default settings
            $InitialSplat = @{
                Path         = "$env:APPDATA\LoganShell\"
                SCCM         = $EnableSCCM
                SCCMServer   = $SCCMServerInput
                Exchange     = $EnableExchange
                DefaultDC    = $PDC
                ObjectFolder = $ObjectFolder
            }
            _InitialSettings @InitialSplat -ErrorAction Stop
        }
        catch {
            throw $_
        }
        Write-Verbose 'Done setting up for first run.'
    }
    #endregion

    #region Loading Settings
    Write-Verbose 'Loading Settings'
    try {
        _LoadSettings -File $env:APPDATA\LoganShell\Settings.json -ErrorAction Stop
    }
    catch {
        throw $_
    }

    if ($ShowSettings) {
        Write-Output ($STTSettings | ConvertTo-Json)
        break
    }

    if ($STTSettings.Theme) {
        switch ($STTSettings.Theme) {
            'Light' {
                $ThemeFile = "$ModuleRoot\Assets\LightTheme.xaml"
            }
            'Dark' {
                $ThemeFile = "$ModuleRoot\Assets\DarkTheme.xaml"
            }
            'Violet' {
                $ThemeFile = "$ModuleRoot\Assets\VioletTheme.xaml"
            }
            Default {
                $ThemeFile = "$ModuleRoot\Assets\LightTheme.xaml"
            }
        }
    }
    else {
        # Old settings file
        $ThemeFile = "$ModuleRoot\Assets\LightTheme.xaml"
    }
    #endregion

    Write-Verbose 'Starting to launch window'

    switch ($QuickLaunch) {
        'ADLookups' {
            _NewXAMLWindow -FormName 'ADLookups'
            _ADLookupsUIEvents
            Write-Output 'Loading ADLookups....'
            $null = $ADLookups.ShowDialog()
        }
        'RSOP' {
            _NewXAMLWindow -FormName 'RSOP'
            _RSOPWindowUIEvents
            Write-Output 'Loading RSOP....'
            $null = $RSOP.ShowDialog()
        }
        'SCCMDeployments' {
            _NewXAMLWindow -FormName 'SCCMDeployments'
            _SCCMDeploymentsUIEvents
            Write-Output 'Loading SCCM Deployments....'
            $null = $SCCMDeployments.ShowDialog()
        }
        'ComputerStats' {
            _NewXAMLWindow -FormName 'ComputerStats'
            _ComputerStatsUIEvents
            Write-Output 'Loading Computer Stats....'
            $null = $ComputerStats.ShowDialog()
        }
        'Passphrases' {
            _NewXAMLWindow -FormName 'Passphrases'
            _PassphrasesUIEvents
            Write-Output 'Loading Passphrases....'
            $null = $Passphrases.ShowDialog()
        }
        'WUG' {
            _NewXAMLWindow -FormName 'WhatsUpGold'
            _WhatsUpGoldUIEvents
            Write-Output 'Loading WUG Monitors....'
            $null = $WhatsUpGold.ShowDialog()
        }
        'CmdletHelp' {
            _NewXAMLWindow -FormName 'CmdletHelp'
            _CmdletHelpUIEvents
            Write-Output 'Loading Cmdlet Help....'
            $null = $CmdletHelp.ShowDialog()
        }
        Default {
            _NewXAMLWindow -FormName 'RSOP'
            _RSOPWindowUIEvents

            _NewXAMLWindow -FormName 'ADLookups'
            _ADLookupsUIEvents

            _NewXAMLWindow -FormName 'SCCMDeployments'
            _SCCMDeploymentsUIEvents

            _NewXAMLWindow -FormName 'ComputerStats'
            _ComputerStatsUIEvents

            _NewXAMLWindow -FormName 'Passphrases'
            _PassphrasesUIEvents

            _NewXAMLWindow -FormName 'WhatsUpGold'
            _WhatsUpGoldUIEvents

            _NewXAMLWindow -FormName 'Options'
            _OptionsUIEvents

            _NewXAMLWindow -FormName 'CmdletHelp'
            _CmdletHelpUIEvents

            _NewXAMLWindow -FormName 'HomeWindow'
            _HomeWindowUIEvents

            #region Update Check
            Write-Verbose 'Update Check'
            $UpdateCheck = _CheckForUpdate
            if ($UpdateCheck.Outdated) {
                $HomeWindow_UpdateStatusBarItem.Content = 'Update Found!'
                $MessageSplat = @{
                    MessageText  = "An update was found.`nCurrent version: $($UpdateCheck.Current)`nNew version: $($UpdateCheck.Newest)`nDo you want to update now?`n`nRelease Notes: $($UpdateCheck.ReleaseNotes)"
                    MessageIcon  = 'Asterisk'
                    ButtonType   = 'YesNo'
                    MessageTitle = 'Update Found'
                }
                $Answer = _ShowMessageBox @MessageSplat
                switch ($Answer) {
                    Yes {
                        Update-Module $ModuleName
                        Write-Host 'Module Updated. Open a new powershell session to load the new version.'
                        break
                    }
                    No {
                    }
                    Default {
                    }
                }
            }
            #endregion

            #region External Tools
            _ExternalTools
            #endregion

            Write-Output 'Loading ServerTeamTools....'
            $null = $HomeWindow.ShowDialog()
        }
    }
}