IntegrisPowerShell.psm1

### ======================================================================================================================
### INTEGRIS POWERSHELL MODULE
### ======================================================================================================================

<#---
Nameing Convention:
 
    Verbs:
        GET/SET - Standard Functions to Retrieve Information or Change Settings
        REPORT - Complex Functions, Often With Numerous Parameter Options
        CHECK - Functions for Quickly Gather Information Related to Potential Issues
        SEARCH - Functions for Easier Use of Complex PowerShell Queries
 
    Prefixes:
        Each function should have and 'Int' prefix as the name/alias. This ensures easy tabing through
        of commands from this module.
 
---#>


### ### ==============================================================================================
### ### HELP FUNCTIONS
### ### ==============================================================================================

Function Get-IntegrisPowerShellVersion {

    <#
    .SYNOPSIS
        Lists the version of the Integris PowerShell module.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-IntegrisPowerShellVersion
 
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    Return "1.7.3"
}
Function Get-IntegrisPowerShellDirectory {

    <#
.SYNOPSIS
    Lists a directory of all the commands in the Integris PowerShell module.
 
.DESCRIPTION
 
    PARAMETERS
        N/A
 
    NOTES
        N/A
 
    TIPS
        N/A
 
.EXAMPLE
    Get-IntegrisPowerShellDirectory
 
.LINK
    https://bjn.itglue.com/1902395/docs/14305861
#>


    Write-Host ""
    Write-Host "INTEGRIS POWERSHELL DIRECTORY"
    Write-Host "====================================="
    Write-Host ""
    Write-Host " Function Types"
    Write-Host " ====================================="
    Write-Host " GET - Return Basic Information (ex. GET-RecentCrashes, GET-MonitorInformation)"
    Write-Host " SET - Configure Basic Settings (ex. SET-LocalAccountEnumeration, SET-FastUserSwitching)"
    Write-Host " FIX - Quick Fixes for Common Problems (ex. FIX-MicrosoftOfficeLogin)"
    Write-Host " SEARCH - Complex Functions That Accept Multiple Inputs to Give Customizable Results (ex. SEARCH-EventLog)"
    Write-Host " REPORT - Gather Detailed Pre-Configured Information Sets (ex. REPORT-PCSummary,REPORT-PCPerformance)"
    Write-Host " AUDIT - Functions Design to Assit with Auditing and Enforcing Security Standards (ex. Audit-NTFSPermissions)"
    Write-Host " CHECK - Automated Diagnotic Functions That Attempt to Highlight Possible Issues (ex. CHECK-DNS, CHECK-NetworkConnection)"
    Write-Host ""
    Write-Host ""
    Write-Host " GET\SET Functions"
    Write-Host " ====================================="
    Write-Host ""
    Write-Host " Hardware Information"
    Write-Host " ====================================="            
    Write-Host " Get-ProcessorName (Returns the Model information for the CPU)"
    Write-Host " Get-EnclosureType (Returns the Form Factor of the Computer Case)"
    Write-Host " Get-RAMSlots (Lists the RAM Slots and Memory in Each Slot)"
    Write-Host " Get-RAMGBsInstalled (Returns the Total GBs of RAM Installed)"
    Write-Host " Get-VideoDevices (Lists Video Output Devices)"
    Write-Host " Get-RealNetworkAdapters (Lists Real Network Adapters (i.e. Not VPN and Virtual Adapters)"
    Write-Host " Get-CPUScore (Returns the CPU Score as Benchmarked by CPUBenchmark.net)"
    Write-Host " Get-PCAge (Returns the Approximate Age of the Computer Based on CPU Release Date)"
    Write-Host " Get-DiskPerformance (Runs a Disk Benchmark and Lists the Results)"
    Write-Host ""
    Write-Host " Software Information"
    Write-Host " ====================================="
    Write-Host " Get-InstalledApplications (Lists Installed Applications)"
    Write-Host " Get-RecentMSIUninstalls (Lists Recently Uninstall MSI Applications)"
    Write-Host " Get\Set-OutlookMailboxCacheMode (Returns or Changes the Outlook Mailbox Cache Mode for All Users)"
    Write-Host " Get\Set-OneDriveBackupStatus (Returns or Changes Whether the OneDrive Backup Feature is Allowed)"   
    Write-Host ""
    Write-Host " Operating System Information"
    Write-Host " ====================================="         
    Write-Host " Get-RecentLogons (Lists User Logons)"
    Write-Host " Get-RecentUpdates (Lists Windows Updates)"
    Write-Host " Get-RecentCrashes (Lists BSODs and Power Loss Events)"
    Write-Host " Get-UserProfiles (Lists Windows Profiles)"
    Write-Host " Get\Set-FastUserSwitching (List or Change the Status of the Fast User Switching Feature)"  
    Write-Host " Get\Set-LocalAccountEnumeration (List or Change the Status of the Local Account Enumeration Feature)"
    Write-Host " Get\Set-AdapterIPv6Status (Enable or Disable IPv6 on All Adapters)"
    Write-Host ""
    Write-Host " USB and Peripheral Information"
    Write-Host " ====================================="
    Write-Host " Get-MonitorInformation (List Monitor Info, Including Year, Serial, and In-Use Connector)"
    Write-Host " Get-USBAudio (Lists Connected USB Audio Devices)" 
    Write-Host " Get-USBCameras (Lists COnnected USB Cameras)"
    Write-Host " Get-USBPrinters (Lists Connected USB Printers)"
    Write-Host " Get-DocumentScanners (Lists Connected Document Scanners)"
    Write-Host ""
    Write-Host " Security Information"
    Write-Host " ====================================="
    Write-Host " Get-CryptoProtocols (Lists Enable Crypto Protocols)"
    Write-Host ""
    Write-Host ""
    Write-Host " FIX Functions"
    Write-Host " ====================================="
    Write-Host " Fix-MicrosoftOfficeLogin (Fixes for Microsoft Office Login Issues)"
    Write-Host ""
    Write-Host ""
    Write-Host " SEARCH Functions"
    Write-Host " ====================================="
    Write-Host " Search-EventLog (Search Event Log for Keywords or Other Options)"
    Write-Host ""
    Write-Host ""
    Write-Host " REPORT Functions"
    Write-Host " ====================================="
    Write-Host " Report-PCSummary (Generates a Report of PC Items Like Monitors, USB Devices, Software, etc)"
    Write-Host " Report-PCPerformance (Generates a Report of PC Performance and Rating for CPU, RAM, and Disk)"
    Write-Host ""
    Write-Host ""
    Write-Host " AUDIT Functions"
    Write-Host " ====================================="
    Write-Host " Audit-NTFSPermissions (Generates a Report of NTFS Permissions)"
    Write-Host " Audit-ADGroupMembership (Generates a Report of AD Group Memberships)"
    Write-Host ""
    Write-Host ""    
    Write-Host " CHECK Functions"
    Write-Host " ====================================="
    Write-Host " Check-DNS (In Development)"
    Write-Host " Check-NetworkConnection (In Development)"
    Write-Host " Check-All (Automatically Checks for Various OS, Networking, and Security Issues)"
    Write-Host ""
    Write-Host ""
    return
}

Export-ModuleMember -Function Get-IntegrisPowerShellVersion
Export-ModuleMember -Function Get-IntegrisPowerShellDirectory -Alias Get-IntegrisPowerShellHelp

### ### ==============================================================================================
### ### GET\SET FUNCTIONS
### ### ==============================================================================================

### ### ### ======================================================================
### ### ### ONEDRIVE FUNCTIONS
### ### ### ======================================================================

Function Get-OneDriveBackupStatus {

    <#
    .SYNOPSIS
        Gets the status of the OneDrive backup option.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-OneDriveBackupStatus
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>

 
    $ItemProp = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -Name KFMBLockOptIn -ErrorAction SilentlyContinue
    IF ($ItemProp.Value -eq 0 -or $ItemProp -eq $null) {
        Return "OneDrive Backup is Allowed"
    }
    ELSE { Return "OneDrive Backup is Disabled" }
}
Function Set-OneDriveBackupStatus {

    <#
    .SYNOPSIS
        Sets the status of the OneDrive backup option.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Set-OneDriveBackupStatus
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>

 
    param(
        [Parameter(Mandatory, ParameterSetName="Enable")]
        [Switch]$Enable = $False,

        [Parameter(Mandatory, ParameterSetName="Disable")]
        [Switch]$Disable = $False
    )

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }
    
    IF ($Enable -eq $True) {
        New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -ErrorAction SilentlyContinue
        New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -Name KFMBlockOptIn -Value 0 -ErrorAction SilentlyContinue
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -Name KFMBlockOptIn -Value 0 -ErrorAction SilentlyContinue
    }

    IF ($Disable -eq $True) {
        New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -ErrorAction SilentlyContinue
        New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -Name KFMBlockOptIn -Value 1 -ErrorAction SilentlyContinue
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive" -Name KFMBlockOptIn -Value 1 -ErrorAction SilentlyContinue
    }
}

Export-ModuleMember -Function Get-OneDriveBackupStatus
Export-ModuleMember -Function Set-OneDriveBackupStatus

### ### ### ======================================================================
### ### ### OUTLOOK FUNCTIONS
### ### ### ======================================================================

Function Set-OutlookMailboxCacheMode {

    <#
    .SYNOPSIS
        Sets Outlook cache mode for all users on the computer.
 
    .DESCRIPTION
 
        PARAMETERS
            -CacheMode PrimaryAndShared (Sets the Cache Mode to Primary and Shared Mailboxes)
            -CacheMode PrimaryOnly (Sets the Cache Mode to Primary Mailbox Only)
            -CacheMode None (Sets the Cache Mode to None, Online Mode Only)
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Set-OutlookMailboxCacheMode -CacheMode None (Sets the Cache Mode to None, Online Mode Only)
 
        Sets all user's Outlook to online mode only.
 
    .EXAMPLE
        Set-OMCM -CacheMode PrimaryAndShared (Sets the Cache Mode to Primary and Shared Mailboxes)
 
        Enabled cache mode for all users for all mailboxes.
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    param(
        [Parameter(Mandatory, ParameterSetName = 'CacheMode')]
        [ValidateSet("PrimaryAndShared","PrimaryOnly","None")]
        [String]$CacheMode
    )    
    
    function Set-RegistryValueForAllUsers { 
    <#
    .SYNOPSIS
        This function uses Active Setup to create a "seeder" key which creates or modifies a user-based registry value
        for all users on a computer. If the key path doesn't exist to the value, it will automatically create the key and add the value.
    .EXAMPLE
        PS> Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'Setting'; 'Type' = 'String'; 'Value' = 'someval'; 'Path' = 'SOFTWARE\Microsoft\Windows\Something'}
      
        This example would modify the string registry value 'Type' in the path 'SOFTWARE\Microsoft\Windows\Something' to 'someval'
        for every user registry hive.
    .PARAMETER RegistryInstance
         A hash table containing key names of 'Name' designating the registry value name, 'Type' to designate the type
        of registry value which can be 'String,Binary,Dword,ExpandString or MultiString', 'Value' which is the value itself of the
        registry value and 'Path' designating the parent registry key the registry value is in.
    #>
 
    [CmdletBinding()] 
    param ( 
        [Parameter(Mandatory=$true)] 
        [hashtable[]]$RegistryInstance 
    ) 
    try { 
        New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null 
         
        ## Change the registry values for the currently logged on user. Each logged on user SID is under HKEY_USERS
        $LoggedOnSids = (Get-ChildItem HKU: | where { $_.Name -match 'S-\d-\d+-(\d+-){1,14}\d+$' }).PSChildName 
        Write-Host "Found $($LoggedOnSids.Count) logged on user SIDs" 
        foreach ($sid in $LoggedOnSids) { 
            Write-Host -Message "Loading the user registry hive for the logged on SID $sid" 
            foreach ($instance in $RegistryInstance) { 
                ## Create the key path if it doesn't exist
                New-Item -ErrorAction SilentlyContinue -Path ("HKU:\$sid\$($instance.Path)" | Split-Path -Parent) -Name ("HKU:\$sid\$($instance.Path)" | Split-Path -Leaf) | Out-Null
                ## Create (or modify) the value specified in the param
                New-Item -Path "HKU:\$sid\SOFTWARE\Policies\Microsoft\Office" -ErrorAction SilentlyContinue
                New-Item -Path "HKU:\$sid\SOFTWARE\Policies\Microsoft\Office\16.0" -ErrorAction SilentlyContinue
                New-Item -Path "HKU:\$sid\SOFTWARE\Policies\Microsoft\Office\16.0\Outlook" -ErrorAction SilentlyContinue
                New-Item -Path "HKU:\$sid\SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode" -ErrorAction SilentlyContinue

                Set-ItemProperty -Path "HKU:\$sid\$($instance.Path)" -Name $instance.Name -Value $instance.Value -Type $instance.Type -Force 
            } 
        } 
         
        ## Create the Active Setup registry key so that the reg add cmd will get ran for each user
        ## logging into the machine.
        ## http://www.itninja.com/blog/view/an-active-setup-primer
        Write-Host "Setting Active Setup registry value to apply to all other users" 
        foreach ($instance in $RegistryInstance) { 
            ## Generate a unique value (usually a GUID) to use for Active Setup
            $Guid = [guid]::NewGuid().Guid 
            $ActiveSetupRegParentPath = 'HKLM:\Software\Microsoft\Active Setup\Installed Components' 
            ## Create the GUID registry key under the Active Setup key
            New-Item -ErrorAction SilentlyContinue -Path $ActiveSetupRegParentPath -Name $Guid | Out-Null 
            $ActiveSetupRegPath = "HKLM:\Software\Microsoft\Active Setup\Installed Components\$Guid" 
            Write-Host "Using registry path '$ActiveSetupRegPath'" 
             
            ## Convert the registry value type to one that reg.exe can understand. This will be the
            ## type of value that's created for the value we want to set for all users
            switch ($instance.Type) { 
                'String' { 
                    $RegValueType = 'REG_SZ' 
                } 
                'Dword' { 
                    $RegValueType = 'REG_DWORD' 
                } 
                'Binary' { 
                    $RegValueType = 'REG_BINARY' 
                } 
                'ExpandString' { 
                    $RegValueType = 'REG_EXPAND_SZ' 
                } 
                'MultiString' { 
                    $RegValueType = 'REG_MULTI_SZ' 
                } 
                default { 
                    throw "Registry type '$($instance.Type)' not recognized" 
                } 
            } 
             
            ## Build the registry value to use for Active Setup which is the command to create the registry value in all user hives
            $ActiveSetupValue = "reg add `"{0}`" /v {1} /t {2} /d {3} /f" -f "HKCU\$($instance.Path)", $instance.Name, $RegValueType, $instance.Value 
            Write-Host -Message "Active setup value is '$ActiveSetupValue'" 
            ## Create the necessary Active Setup registry values
            Set-ItemProperty -Path $ActiveSetupRegPath -Name '(Default)' -Value 'Active Setup Test' -ErrorAction SilentlyContinue
            Set-ItemProperty -Path $ActiveSetupRegPath -Name 'Version' -Value '1' -ErrorAction SilentlyContinue
            Set-ItemProperty -Path $ActiveSetupRegPath -Name 'StubPath' -Value $ActiveSetupValue -ErrorAction SilentlyContinue
        } 
    } catch { 
        Write-Warning -Message $_.Exception.Message 
    } 
}

    IF($CacheMode -eq "PrimaryAndShared") {
        IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
             Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
             Return
        }    

        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'CacheOthersMail'; 'Type' = 'DWORD'; 'Value' = '1'; 'Path' = 'SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'}
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'DownloadSharedFolders'; 'Type' = 'DWORD'; 'Value' = '1'; 'Path' = 'SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'}
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'Enable'; 'Type' = 'DWORD'; 'Value' = '1'; 'Path' = 'SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'}
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'NoOST'; 'Type' = 'DWORD'; 'Value' = '0'; 'Path' = 'SOFTWARE\Microsoft\Office\16.0\Outlook\OST'}
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'SyncWindowSetting'; 'Type' = 'DWORD'; 'Value' = '36'; 'Path' = 'Software\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'}
     }

    IF($CacheMode -eq "PrimaryOnly") {
        IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
             Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
             Return
        }    
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'CacheOthersMail'; 'Type' = 'DWORD'; 'Value' = '0'; 'Path' = 'SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'}
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'DownloadSharedFolders'; 'Type' = 'DWORD'; 'Value' = '0'; 'Path' = 'SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'}
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'Enable'; 'Type' = 'DWORD'; 'Value' = '1'; 'Path' = 'SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'}
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'NoOST'; 'Type' = 'DWORD'; 'Value' = '0'; 'Path' = 'SOFTWARE\Microsoft\Office\16.0\Outlook\OST'}
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'SyncWindowSetting'; 'Type' = 'DWORD'; 'Value' = '36'; 'Path' = 'Software\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'}
    }

    IF($CacheMode -eq "None") {
        IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
             Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
             Return
        }    
        While (Get-Process "Outlook" -ErrorAction SilentlyContinue) {
        taskkill /IM “outlook.exe” /f
        Start-Sleep -Seconds 5
        }
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'CacheOthersMail'; 'Type' = 'DWORD'; 'Value' = '0'; 'Path' = 'SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'}
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'Enable'; 'Type' = 'DWORD'; 'Value' = '0'; 'Path' = 'SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'}
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'DownloadSharedFolders'; 'Type' = 'DWORD'; 'Value' = '0'; 'Path' = 'SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'}
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'NoOST'; 'Type' = 'DWORD'; 'Value' = '2'; 'Path' = 'SOFTWARE\Microsoft\Office\16.0\Outlook\OST'}
        FOREACH ($Profile in $Profiles) {
            $SearchPath = $Profile.FullName + "\AppData\Local\Microsoft\Outlook"
            $OSTs = Get-ChildItem -Path $SearchPath -ErrorAction SilentlyContinue | where { $_.Name -like "*.ost*" } 
            FOREACH ($OST in $OSTs) {
                Remove-Item $OST.FullName
            }
        }
    } 
}

Export-ModuleMember -Function Set-OutlookMailboxCacheMode

### ### ### ======================================================================
### ### ### SECURITY FUNCTIONS
### ### ### ======================================================================

Function Get-CryptoProtocols {

    <#
    .SYNOPSIS
        Checks which crypto security procotols are enabled.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-CryptoProtocols
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    $Protocols = ""

    $Key = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\PCT 1.0\Client\' 
    IF (Test-Path $Key) { 
        $Value = Get-ItemProperty $Key 
        IF ($Value.DisabledByDefault -eq 0 -and $Value.Enabled -ne 0) { $Protocols += ", PCT 1.0" } 
    }
    ELSE { $Protocols += ", PCT 1.0" }

    $Key = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client\' 
    IF (Test-Path $Key) { 
        $Value = Get-ItemProperty $Key 
        IF ($Value.DisabledByDefault -eq 0 -and $Value.Enabled -ne 0) { $Protocols += ", SSL 2.0" } 
    }
    ELSE { $Protocols += ", SSL 2.0" }

    $Key = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client\' 
    IF (Test-Path $Key) { 
        $Value = Get-ItemProperty $Key 
        IF ($Value.DisabledByDefault -eq 0 -and $Value.Enabled -ne 0) { $Protocols += ", SSL 3.0" } 
    }
    ELSE { $Protocols += ", SSL 3.0" }

    $Key = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client\' 
    IF (Test-Path $Key) { 
        $Value = Get-ItemProperty $Key 
        IF ($Value.DisabledByDefault -eq 0 -and $Value.Enabled -ne 0) { $Protocols += ", TLS 1.0" } 
    }
    ELSE { $Protocols += ", TLS 1.0" }

    $Key = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client\' 
    IF (Test-Path $Key) { 
        $Value = Get-ItemProperty $Key 
        IF ($Value.DisabledByDefault -eq 0 -and $Value.Enabled -ne 0) { $Protocols += ", TLS 1.1" } 
    }
    ELSE { $Protocols += ", TLS 1.1" }

    $Key = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client\' 
    IF (Test-Path $Key) { 
        $Value = Get-ItemProperty $Key 
        IF ($Value.DisabledByDefault -eq 0 -and $Value.Enabled -ne 0) { $Protocols += ", TLS 1.2" } 
    }
    ELSE { $Protocols += ", TLS 1.2" }

    return $Protocols.Substring(2,$Protocols.Length-2)
}
Function Get-WindowsFirewallStatus {

    <#
    .SYNOPSIS
        Lists Windows Firewall profiles and their status.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-WindowsFirewallStatus
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    $FWProfiles = Get-NetFirewallProfile
    return $FWProfiles | select Name,Enabled
}

Export-ModuleMember -Function Get-CryptoProtocols
Export-ModuleMember -Function Get-WindowsFirewallStatus

### ### ### ======================================================================
### ### ### OPERATING SYSTEM FUNCTIONS
### ### ### ======================================================================

Function Get-OperatingSystemName {

    <#
    .SYNOPSIS
        Gets the friendly name of the operating system.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-OperatingSystemName
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    (Get-WmiObject Win32_OperatingSystem).Caption
}
Function Get-FastUserSwitching {

    <#
    .SYNOPSIS
        Gets the status of the Fast User Switching feature.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-FastUserSwitching
 
        Returns if the Fast User Switching feature is enabled or disabled.
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>

    
    $FastUserSwitching = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name HideFastUserSwitching -ErrorAction SilentlyContinue
    IF($FastUserSwitching.HideFastUserSwitching -eq 1) { return "Fast User Switching: Disabled" }
    ELSEIF($FastUserSwitching.HideFastUserSwitching -eq 0) { return "Fast User Switching: Enabled" }
    ELSE { return "Fast User Switching: Enabled" }
}
Function Set-FastUserSwitching { 

    <#
    .SYNOPSIS
        Sets the status of the Fast User Switching feature.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Set-FastUserSwitching -Enable
 
        Enables the Fast User Switching feature.
 
    .EXAMPLE
        Set-FastUserSwitching -Disable
 
        Disables the Fast User Switching feature.
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    param(
        [Parameter(Mandatory, ParameterSetName="Enable")]
        [Switch]$Enable = $False,

        [Parameter(Mandatory, ParameterSetName="Disable")]
        [Switch]$Disable = $False
    )

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }
    
    IF ($Enable -eq $True) {
        New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies" -ErrorAction SilentlyContinue -ErrorAction SilentlyContinue
        New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -ErrorAction SilentlyContinue -ErrorAction SilentlyContinue
        New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name HideFastUserSwitching -Value 0 -ErrorAction SilentlyContinue
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name HideFastUserSwitching -Value 0 -ErrorAction SilentlyContinue
    }

    IF ($Disable -eq $True) {
        New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies" -ErrorAction SilentlyContinue -ErrorAction SilentlyContinue
        New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -ErrorAction SilentlyContinue -ErrorAction SilentlyContinue
        New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name HideFastUserSwitching -Value 1 -ErrorAction SilentlyContinue
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name HideFastUserSwitching -Value 1 -ErrorAction SilentlyContinue
    }
}
Function Get-LocalAccountEnumeration {

    <#
    .SYNOPSIS
        Gets the status of the Local Account Enumeration feature.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-LocalAccountEnumeration
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    $LocalAccountEnumeration = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name EnumerateLocalUsers -ErrorAction SilentlyContinue
    IF($LocalAccountEnumeration.EnumerateLocalUsers -eq 0) { return "Enumerate Local Users: Disabled" }
    ELSEIF($LocalAccountEnumeration.EnumerateLocalUsers -eq 1) { return "Enumerate Local Users: Enabled" }
    ELSE { return "Enumerate Local Users: Disabled" }
}
Function Set-LocalAccountEnumeration { 

    <#
    .SYNOPSIS
        Sets the status of the Local Account Enumeration feature.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            Enabling this setting allows users to see local accounts in the bottom left of the screen on a domain joined computer. Without this setting the only options that will show are the last logged in user\currently logged in users, and 'Other User'.
 
        TIPS
            N/A
 
    .EXAMPLE
        Set-LocalAccountEnumeration -Enable
 
        Enables the Local Account Enumeration feature.
 
    .EXAMPLE
        Set-LocalAccountEnumeration -Disable
 
        Disables the Local Account Enumeration feature.
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    param(
        [Parameter(Mandatory, ParameterSetName="Enable")]
        [Switch]$Enable = $False,

        [Parameter(Mandatory, ParameterSetName="Disable")]
        [Switch]$Disable = $False
    )
    
    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }
    
    IF ($Enable -eq $True) {
        New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name EnumerateLocalUsers -Value 1 -ErrorAction SilentlyContinue
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name EnumerateLocalUsers -Value 1 -ErrorAction SilentlyContinue
    }

    IF ($Disable -eq $True) {
        New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name EnumerateLocalUsers -Value 0 -ErrorAction SilentlyContinue
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name EnumerateLocalUsers -Value 0 -ErrorAction SilentlyContinue
    }
}
Function Get-RecentCrashes {

    <#
    .SYNOPSIS
        Lists recent crashes found in the event log.
 
    .DESCRIPTION
 
        PARAMETERS
            -Days (Integer) (Specify the number of days back to check for crashes. Default is 60.)
            -Count (Integer) (Specify the number of events to find. Default is unlimited.)
            -All (Use to search through entire event log for crashes.)
            -OnlyBSOD (Use to find only BSOD crashes.)
            -OnlyPower (Use to find only power loss events.)
     
        NOTES
            N/A
 
        TIPS
            You can use CW Automate or a similar application to run this script and open tickets. For example, if you wanted to proactively respond to computers crashing you could have CW Automate open a ticket if more than 5 BSODs are found in the last 60 days.
 
    .EXAMPLE
        Get-RecentCrashes
 
        Lists all crashes in the last 90 days.
     
    .EXAMPLE
        Get-RecentCrashes -Days 180
 
        Lists all crashes in the last 180 days.
 
    .EXAMPLE
        Get-RecentCrashes -All
 
        Lists all crashes found in the event log.
 
    .EXAMPLE
        Get-RecentCrashes -All -BSODOnly
 
        Lists all BSOD crashes found in the event log.
 
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    [CmdletBinding(DefaultParameterSetName='Null')]
    param(
        [Parameter(ParameterSetName = 'Days')]
        [int]$Days = 60,

        [Parameter(ParameterSetName = 'All')]
        [Switch]$All = $False,

        [Parameter(ParameterSetName = 'Count')]
        [Int]$Count = 99999,

        [Parameter(ParameterSetName = 'All')]
        [Parameter(ParameterSetName = 'Days')]
        [Parameter(ParameterSetName = 'Count')]
        [Parameter(ParameterSetName = 'OnlyBSOD')]
        [Switch]$OnlyBSOD = $False,

        [Parameter(ParameterSetName = 'All')]
        [Parameter(ParameterSetName = 'Days')]
        [Parameter(ParameterSetName = 'Count')]
        [Parameter(ParameterSetName = 'OnlyPower')]
        [Switch]$OnlyPower = $False
    )

    $Now = Get-Date
    
    IF ($OnlyBSOD -eq $True) {
        IF ($All -eq $False ) { 
            $Events = Get-EventLog -LogName System -Source BugCheck -After $now.AddDays(-$Days) -Newest $Count -ErrorAction SilentlyContinue
        }
        ELSE { 
            $Events = Get-EventLog -LogName System -Source BugCheck -ErrorAction SilentlyContinue
        }
        return
    }

    IF ($OnlyPower -eq $True) {
        IF ($All -eq $False ) { 
            $Events = Get-EventLog -LogName System -InstanceId 41 -After $now.AddDays(-$Days) -Newest $Count -ErrorAction SilentlyContinue
        }
        ELSE { 
            $Events = Get-EventLog -LogName System -InstanceId 41 -ErrorAction SilentlyContinue
        }
        return
    }

    IF ($All -eq $False ) { 
        $Events = Get-EventLog -LogName System -Source BugCheck -After $now.AddDays(-$Days) -Newest $Count -ErrorAction SilentlyContinue
        $Events += Get-EventLog -LogName System -InstanceId 41 -After $now.AddDays(-$Days) -Newest $Count -ErrorAction SilentlyContinue
    }
    ELSE { 
        $Events = Get-EventLog -LogName System -Source BugCheck -ErrorAction SilentlyContinue
        $Events += Get-EventLog -LogName System -InstanceId 41 -ErrorAction SilentlyContinue
    } 
    $Events | Sort-Object -Property Index -Descending
}
Function Get-RecentUpdates {

    <#
    .SYNOPSIS
        Lists recent Windows updates.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-RecentUpdates
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    Get-HotFix | Sort-Object -Property InstalledOn -Descending
}
Function Get-UserProfiles {

    <#
    .SYNOPSIS
        Lists user profiles.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-UserProfiles
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    $Profiles = Get-ChildItem -Path C:\Users -Directory
    FOREACH ($Profile in $Profiles) { 
        IF($Profile.Name -ne "Public" -and $Profile.Name  -ne "public" -and $Profile.Name  -ne "admin" -and $Profile.Name  -ne "Admin" -and $Profile.Name  -ne "Administrator" -and $Profile.Name  -ne "administrator" -and $Profile.Name  -ne "Labtech" -and $Profile.Name  -ne "labtech" -and $Profile.Name  -ne "bjnadmin" -and $Profile.Name  -ne "cyberhawk" -and $Profile.Name  -ne "DefaultAppPool" -and $Profile.Name  -ne "labtechservice") 
            { Write-Host $Profile.Name } 
        }
}
Function Get-RecentMSIUninstalls {

    <#
    .SYNOPSIS
        Lists recently uninstalled MSI applications.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            This only shows applications uninstalled using MSI installers. Applications uninstalled with EXEs are not included.
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-RecentMSIUninstalls
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>

    
    $Results = Get-Eventlog -LogName Application -InstanceId 1034,11724 | select Source, UserName, TimeWritten, Message
    return $Results
}
Function Get-RecentLogons {

    <#
    .SYNOPSIS
        Returns a list of the most recent logins from the event log.
 
    .DESCRIPTION
 
        PARAMETERS
            -Count (Integer) (Returns only the number of recent logons specified.)
            -All (Returns all recent logons found in the event log.)
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-RecentLogons
 
        Returns the 10 most recent logons.
 
    .EXAMPLE
        Get-RecentLogons -Count ##
 
        Returns the number of recent logons specified.
 
    .EXAMPLE
        Get-RL -All
 
        Returns all recent logons found in the event log.
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


     [CmdletBinding(DefaultParameterSetName='Null')]
     param(
        [Parameter(ParameterSetName = 'Count')]
        [int]$Count = 10,

        [Parameter(ParameterSetName = 'All')]
        [Switch]$All = $False
    )       
   
    IF ($All -eq $true) { $logs = get-eventlog system -source Microsoft-Windows-Winlogon -InstanceId 7001}
    ELSE { $logs = get-eventlog system -source Microsoft-Windows-Winlogon -InstanceId 7001 -Newest $Count -ErrorAction SilentlyContinue }
    $res = @(); ForEach ($log in $logs) {
        if($log.instanceid -eq 7001) { $type = "Logon" } 
        Elseif ($log.instanceid -eq 7002){ $type="Logoff" } 
        Else { Continue } 
        
        try { 
            $res += New-Object PSObject -WarningAction Ignore -Property @{Time = $log.TimeWritten; "Event" = $type; User = (New-Object System.Security.Principal.SecurityIdentifier $Log.ReplacementStrings[1]).Translate([System.Security.Principal.NTAccount])} -ErrorAction Ignore
        } catch { }

     }

    $res | Format-Table -AutoSize
}

Export-ModuleMember -Function Get-OperatingSystemName
Export-ModuleMember -Function Get-FastUserSwitching
Export-ModuleMember -Function Set-FastUserSwitching
Export-ModuleMember -Function Get-LocalAccountEnumeration
Export-ModuleMember -Function Set-LocalAccountEnumeration
Export-ModuleMember -Function Get-RecentCrashes
Export-ModuleMember -Function Get-RecentUpdates
Export-ModuleMember -Function Get-UserProfiles
Export-ModuleMember -Function Get-RecentMSIUninstalls
Export-ModuleMember -Function Get-RecentLogons

### ### ### ======================================================================
### ### ### NETWORKING FUNCTIONS
### ### ### ======================================================================

Function Get-AdapterIPv6Status {

    <#
    .SYNOPSIS
        Gets the status of the IPv6 adapters.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-AdapterIPv6Status
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    Get-NetAdapterBinding | Where-Object ComponentID -EQ 'ms_tcpip6' | Select Name,DisplayName,Enabled
}
Function Set-AdapterIPv6Status { 

    <#
    .SYNOPSIS
        Sets the status of the IPv6 adapters.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            Use this command to quick enable or disable all IPv6 adapters on a computer.
 
        TIPS
            Disabling IPv6 can be something worth trying when diagnosing intermittent connectivity issues with computers.
 
    .EXAMPLE
        Set-AdapterIPv6Status -Enable
 
        Enables all IPv6 adapters.
 
    .EXAMPLE
        Set-AdapterIPv6Status -Disable
 
        Disables all IPv6 adapters.
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>

    
    param(
        [Parameter(Mandatory, ParameterSetName="Enable")]
        [Switch]$Enable = $False,

        [Parameter(Mandatory, ParameterSetName="Disable")]
        [Switch]$Disable = $False
    )

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }

    $IPv6Bindings = Get-NetAdapterBinding | Where-Object ComponentID -EQ 'ms_tcpip6'
    
    IF ($Enable -eq $True) {
        FOREACH ($IPv6Binding in $IPv6Bindings) {
            Enable-NetAdapterBinding -Name $IPv6Binding.Name -ComponentID 'ms_tcpip6'
        }
    }

    IF ($Disable -eq $True) {
        FOREACH ($IPv6Binding in $IPv6Bindings) {
            Disable-NetAdapterBinding -Name $IPv6Binding.Name -ComponentID 'ms_tcpip6'
        }
    }
}
Function Get-WiredConnection {
    $ReturnVar = @("", "")
    $var1 = $null
    $var1 = Get-NetAdapter | Where-Object { $_.Status -eq "Up" -and $_.Name -ne "Wi-Fi" -and $_.InterfaceDescription -ne "Hyper-V Virtual Ethernet Adapter" -and $_.InterfaceDescription -notlike "*SonicWall*" }
    IF ($var1 -eq $null) { $Status = "Disconnected" }
    IF ($var1 -ne $null) { $Status = "Connected" }
    return $Status
}
Function Get-WiredLinkSpeed {
    $var1 = $null
    $var1 = Get-NetAdapter | Where-Object { $_.Status -eq "Up" -and $_.Name -ne "Wi-Fi" -and $_.InterfaceDescription -ne "Hyper-V Virtual Ethernet Adapter" -and $_.InterfaceDescription -notlike "*SonicWall*"  }
    IF ($var1 -eq $null) { $ReturnVar = "N/A"; return $ReturnVar }
    IF ($var1.LinkSpeed -like "*Mbps*") { $ReturnVar = $var1.LinkSpeed; return $ReturnVar }
    ELSE { $ReturnVar = $var1.LinkSpeed; return $ReturnVar }
}
Function Get-WiFiConnection {
    $var1 = netsh wlan show interfaces | select-string -Pattern "[\s]SSID"
    IF ($var1 -eq $null) {
        $var2 = Get-NetAdapter -Name "Wi-Fi" -ErrorAction SilentlyContinue
        IF ($var2 -eq $null) { 
            $ReturnVar = "Disconnected"
            return $ReturnVar  
        }
        IF ($var2.status -ne "Up") { 
            $ReturnVar = "Disconnected"
            return $ReturnVar 
        }
    }
    $var1 = netsh wlan show interfaces | select-string -Pattern "[\s]Radio Type"
    $var1 = $var1.tostring().replace(" Radio type : ","")
    IF($var1 -eq "802.11ac") { return "802.11ac" }
    IF($var1 -eq "802.11ax") { return "802.11ax" }
    return $var1
}
Function Get-WiFiSignalStrength {
    $var1 = netsh wlan show interfaces | select-string -Pattern "[\s]SSID"
    IF ($var1 -eq $null) {
        $var2 = Get-NetAdapter -Name "Wi-Fi" -ErrorAction SilentlyContinue
        IF ($var2 -eq $null) { 
            $ReturnVar = "N/A"
            return $ReturnVar  
        }
        IF ($var2.status -ne "Up") { 
            $ReturnVar = "N/A"
            return $ReturnVar 
        }
    }
    $var1 = netsh wlan show interfaces | select-string -Pattern "[\s]Signal"
    $var1 = $var1.tostring().replace(" Signal : ","")
    return $var1
}
Function Get-WiFiLinkSpeed {
    $var1 = netsh wlan show interfaces | select-string -Pattern "[\s]SSID"
    IF ($var1 -eq $null) {
        $var2 = Get-NetAdapter -Name "Wi-Fi" -ErrorAction SilentlyContinue
        IF ($var2 -eq $null) { 
            $ReturnVar = "N/A"
            return $ReturnVar  
        }
        IF ($var2.status -ne "Up") { 
            $ReturnVar = "N/A"
            return $ReturnVar 
        }
    }
    $var1 = netsh wlan show interfaces | select-string -Pattern "[\s]Receive"
    $var1 = $var1.tostring().replace(" Receive rate (Mbps) : ","")
    $var2 = netsh wlan show interfaces | select-string -Pattern "[\s]Transmit"
    $var2 = $var1.tostring().replace(" Transmit rate (Mbps) : ","")
    
    return ($var1 + "/" + $var2 + " Mbps")
}

Export-ModuleMember -Function Get-AdapterIPv6Status
Export-ModuleMember -Function Set-AdapterIPv6Status
Export-ModuleMember -Function Get-WiredConnection
Export-ModuleMember -Function Get-WiredLinkSpeed
Export-ModuleMember -Function Get-WiFiConnection
Export-ModuleMember -Function Get-WiFiSignalStrength
Export-ModuleMember -Function Get-WiFiLinkSpeed

### ### ### ======================================================================
### ### ### HARDWARE FUNCTIONS
### ### ### ======================================================================

Function Get-MonitorInformation {

    <#
    .SYNOPSIS
        Lists connected Monitors.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            The accuracy of the information is dependant on the maufacturer.
            The Video port listed is the input of the monitor in question.
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-MonitorInformation
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    $MonitorInstances = GWMI WMIMonitorID -Namespace root\wmi | Select InstanceName
    $MonitorCount = 0
    
    $LongestHardwareID = 0
    $LongestMonitorModel = 0
    $LongestManufacturerName = 0
    $LongestVideoOutput = 0
    $LongestSerialNumber = 0
    $LongestManufactureYear = 0
    
    
    FOREACH ($MonitorInstance in $MonitorInstances) {
        $MonitorCount++

        ### Hardware ID
        $HardwareID = ($MonitorInstance.InstanceName.Split('\'))[1]
        IF ($LongestHardwareID -lt $HardwareID.Length) { $LongestHardwareID = $HardwareID.Length }

        ### Manufacture Year
        $MonitorInfo = GWMI WMIMonitorID -Namespace root\wmi | Where-Object { $_.InstanceName -eq $MonitorInstance.InstanceName }
        $ManufactureYear = "Unknown"
        $ManufactureYear = $MonitorInfo.YearOfManufacture
        IF ($LongestManufactureYear -lt $ManufactureYear.Length) { $LongestManufactureYear = $ManufactureYear.Length }

        ### Serial Number
        $SerialNumber = "Unknown"
        $SerialNumber = [System.Text.Encoding]::ASCII.GetString($MonitorInfo.SerialNumberID).Trim(0x00)
        IF ($LongestSerialNumber -lt $SerialNumber.Length) { $LongestSerialNumber = $SerialNumber.Length }

        $MonitorInfo = GWMI WmiMonitorConnectionParams -Namespace root\wmi | Where-Object { $_.InstanceName -eq $MonitorInstance.InstanceName }
        
        ### Video Connector
        $VideoOutput = "Unknown"
        $VideoOutput = $MonitorInfo.VideoOutputTechnology
        Switch ($VideoOutput) {
            "0" { $VideoOutput = "VGA" }
            "1" { $VideoOutput = "S-Video" }
            "2" { $VideoOutput = "Composite_Video" }
            "3" { $VideoOutput = "Component_Video" }
            "4" { $VideoOutput = "DVI" }
            "5" { $VideoOutput = "HDMI" }
            "6" { $VideoOutput = "LVDS" }
            "7" { $VideoOutput = "Unknown" }
            "8" { $VideoOutput = "D_JPN" }
            "9" { $VideoOutput = "SDI" }
            "10" { $VideoOutput = "DisplayPort" }
            "11" { $VideoOutput = "DisplayPort" }
            "12" { $VideoOutput = "UDI" }
            "13" { $VideoOutput = "UDI" }
            "14" { $VideoOutput = "SDTV_Dongle" }
            "15" { $VideoOutput = "Miracast" }
            "16" { $VideoOutput = "Indirect_Wired" }
            default { $VideoOutput = "Unknown" }
        }
        IF ($LongestVideoOutput -lt $VideoOutput.Length) { $LongestVideoOutput = $VideoOutput.Length }


        $MonitorInfo = Get-PnpDevice | Where-Object { $_.PNPDeviceID -eq $MonitorInfo.InstanceName.Replace("_0","") }

        ### Model
        $MonitorModel = "Unknown"
        $MonitorModel = $MonitorInfo.Name
        IF ($LongestMonitorModel -lt $MonitorModel.Length) { $LongestMonitorModel = $MonitorModel.Length }
        
        ### Vendor
        $MonitorManufacturer = "Unknown"
        $MonitorManufacturer = $MonitorInfo.Manufacturer
        IF ($LongestManufacturerName -lt $MonitorManufacturer.Length) { $LongestManufacturerName = $MonitorManufacturer.Length }
    }
    $MonitorCount = 0
    FOREACH ($MonitorInstance in $MonitorInstances) {
        $MonitorCount++

        ### Hardware ID
        $HardwareID = ($MonitorInstance.InstanceName.Split('\'))[1]
        IF ($LongestHardwareID -lt $HardwareID.Length) { $LongestHardwareID = $HardwareID.Length }

        ### Manufacture Year
        $MonitorInfo = GWMI WMIMonitorID -Namespace root\wmi | Where-Object { $_.InstanceName -eq $MonitorInstance.InstanceName }
        $ManufactureYear = "Unknown"
        $ManufactureYear = $MonitorInfo.YearOfManufacture
        IF ($LongestManufactureYear -lt $ManufactureYear.ToString().Length) { $LongestManufactureYear = $ManufactureYear.ToString().Length }

        ### Serial Number
        $SerialNumber = "Unknown"
        $SerialNumber = [System.Text.Encoding]::ASCII.GetString($MonitorInfo.SerialNumberID).Trim(0x00)
        IF ($LongestSerialNumber -lt $SerialNumber.Length) { $LongestSerialNumber = $SerialNumber.Length }

        $MonitorInfo = GWMI WmiMonitorConnectionParams -Namespace root\wmi | Where-Object { $_.InstanceName -eq $MonitorInstance.InstanceName }
        
        ### Video Connector
        $VideoOutput = "Unknown"
        $VideoOutput = $MonitorInfo.VideoOutputTechnology
        Switch ($VideoOutput) {
            "0" { $VideoOutput = "VGA" }
            "1" { $VideoOutput = "S-Video" }
            "2" { $VideoOutput = "Composite_Video" }
            "3" { $VideoOutput = "Component_Video" }
            "4" { $VideoOutput = "DVI" }
            "5" { $VideoOutput = "HDMI" }
            "6" { $VideoOutput = "LVDS" }
            "7" { $VideoOutput = "Unknown" }
            "8" { $VideoOutput = "D_JPN" }
            "9" { $VideoOutput = "SDI" }
            "10" { $VideoOutput = "DisplayPort" }
            "11" { $VideoOutput = "DisplayPort" }
            "12" { $VideoOutput = "UDI" }
            "13" { $VideoOutput = "UDI" }
            "14" { $VideoOutput = "SDTV_Dongle" }
            "15" { $VideoOutput = "Miracast" }
            "16" { $VideoOutput = "Indirect_Wired" }
            default { $VideoOutput = "Unknown" }
        }
        IF ($LongestVideoOutput -lt $VideoOutput.Length) { $LongestVideoOutput = $VideoOutput.Length }


        $MonitorInfo = Get-PnpDevice | Where-Object { $_.PNPDeviceID -eq $MonitorInfo.InstanceName.Replace("_0","") }

        ### Model
        $MonitorModel = "Unknown"
        $MonitorModel = $MonitorInfo.Name
        IF ($LongestMonitorModel -lt $MonitorModel.Length) { $LongestMonitorModel = $MonitorModel.Length }
        
        ### Vendor
        $MonitorManufacturer = "Unknown"
        $MonitorManufacturer = $MonitorInfo.Manufacturer
        IF ($LongestManufacturerName -lt $MonitorManufacturer.Length) { $LongestManufacturerName = $MonitorManufacturer.Length }

        Write-Host "Monitor" $MonitorCount":" $HardwareID.ToString().Padleft($LongestHardwareID," ") "|" $MonitorModel.ToString().Padleft($LongestMonitorModel," ") "|" $MonitorManufacturer.ToString().Padleft($LongestManufacturerName," ") "|" $VideoOutput.ToString().Padleft($LongestVideoOutput," ") "|" $SerialNumber.ToString().Padleft($LongestSerialNumber," ") "|" $ManufactureYear.ToString().Padleft($LongestManufactureYear," ")
    }
}
Function Get-DocumentScanners {

    <#
    .SYNOPSIS
        Lists connected document scanner devices.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            This can include scanners connected via the network, such as printers with scanners.
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-DocumentScanners
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>

    
    Get-WMIObject Win32_PnPEntity -ErrorAction SilentlyContinue | ? { $_.Service -eq "WSDScan" } | Select Name,Manufacturer
}
Function Get-USBAudio {
    
    <#
    .SYNOPSIS
        Lists connected USB audio devices.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-USBAudio
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    Get-WMIObject Win32_PnPEntity -ErrorAction SilentlyContinue | ? { $_.Service -eq "usbaudio" } | Select Name,Manufacturer
}
Function Get-USBCameras {

    <#
    .SYNOPSIS
        Lists connected USB cameras.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-USBCameras
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    Get-WMIObject Win32_PnPEntity -ErrorAction SilentlyContinue | ? { $_.Service -eq "usbvideo" } | Select Name,Manufacturer
}
Function Get-USBPrinters {

    <#
    .SYNOPSIS
        Lists USB printers.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            This will include offline printers.
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-USBPrinters
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    Get-WMIObject Win32_Printer -ErrorAction SilentlyContinue | Where-Object { $_.PortName -like "*USB*" } | Select Name,DriverName
}
Function Get-VideoDevices {

    <#
    .SYNOPSIS
        Lists connected video devices.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-VideoDevices
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    Get-WMIObject win32_videocontroller -ErrorAction SilentlyContinue | Select Name,AdapterCompatibility
}
Function Get-RAMGBsInstalled {

    <#
    .SYNOPSIS
        Lists total GBs of RAM installed.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-RAMGBsInstalled
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    (Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum / 1gb
}
Function Get-RAMSlots {

    <#
    .SYNOPSIS
        Lists RAM slots and amount of RAM in each slot.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            The RAM slot numbers listed do not correspond to the ram slot numbers on the motherboard.
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-RAMSlots
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    $MemoryArray = Get-WmiObject -Class "Win32_PhysicalMemoryArray"
    $MaxModules = $MemoryArray.MemoryDevices
    $Modules = Get-WmiObject -Class "Win32_PhysicalMemory"
    $Count = 1

    FOREACH ($Module in $Modules) {
        Write-Host "Slot " -NoNewline
        Write-Host $Count.ToString().PadLeft(2,'0') -NoNewline
        Write-Host ": " -NoNewline
        $Capacity = $Module.Capacity / 1GB
        Write-Host $Capacity -NoNewline
        Write-Host "GB"
        $Count++
    }

    WHILE ($Count -le $MaxModules) {
        Write-Host "Slot " -NoNewline
        Write-Host $Count.ToString().PadLeft(2,'0') -NoNewline
        Write-Host ": Empty"
        $Count++
    }
}
Function Get-InstalledApplications {

    <#
    .SYNOPSIS
        Lists installed applications.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-InstalledApplications
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    Get-WMIObject Win32_Product -ErrorAction SilentlyContinue | Where-Object { $_.Name -ne $null -and $_.Name -notlike "*Visual C++*" -and $_.Name -notlike "*Update for Windows*" -and $_.Name -notlike "*Click-to-Run*" } | Select Name,Vendor,Version | Sort-Object -Property Name
}
Function Get-RealNetworkAdapters {

    <#
    .SYNOPSIS
        Lists real network adapters, excludes virtual and VPN adapters.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-RealNetworkAdapters
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    Get-WMIObject Win32_NetworkAdapter -ErrorAction SilentlyContinue | Where-Object { $_.MACAddress -ne $null -and $_.Name -notlike "*Miniport*" -and $_.Name -notlike "*Virtual*" -and $_.Name -notlike "*NetExtender*" -and $_.Name -notlike "*AppGate*" } | Select Name,MACAddress
}
Function Get-ProcessorName {

    <#
    .SYNOPSIS
        Returns the model of the CPU.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-ProcessorName
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    (Get-WMIObject win32_Processor).Name
}
Function Get-EnclosureType {

    <#
    .SYNOPSIS
        Returns the computer case form factor.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-EnclosureType
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    $EnclosureType = Get-WMIObject Win32_SystemEnclosure -ErrorAction SilentlyContinue
    Switch ($EnclosureType.ChassisTypes) {
        "1" { $EnclosureType = "Other" }
        "2" { $EnclosureType = "Unknown" }
        "3" { $EnclosureType = "Desktop" }
        "4" { $EnclosureType = "Low Profile Desktop" }
        "5" { $EnclosureType = "Pizza Box" }
        "6" { $EnclosureType = "Mini Tower" }
        "7" { $EnclosureType = "Tower" }
        "8" { $EnclosureType = "Portable" }
        "9" { $EnclosureType = "Laptop" }
        "10" { $EnclosureType = "Notebook" }
        "11" { $EnclosureType = "Hand Held" }
        "12" { $EnclosureType = "Docking Station" }
        "13" { $EnclosureType = "All in One" }
        "14" { $EnclosureType = "Sub Notebook" }
        "15" { $EnclosureType = "Space-Saving" }
        "16" { $EnclosureType = "Lunch Box" }
        "17" { $EnclosureType = "Main System Chassis" }
        "18" { $EnclosureType = "Expansion Chassis" }
        "19" { $EnclosureType = "SubChassis" }
        "20" { $EnclosureType = "Bus Expansion Chassis" }
        "21" { $EnclosureType = "Peripheral Chassis" }
        "22" { $EnclosureType = "Storage Chassis" }
        "23" { $EnclosureType = "Rack Mount Chassis" }
        "24" { $EnclosureType = "Sealed-Case PC" }
        "30" { $EnclosureType = "Tablet" }
        "31" { $EnclosureType = "Convertible" }
        "32" { $EnclosureType = "Detachable" }
        default { $EnclosureType = "Unknown" }
    }
    return $EnclosureType
}
Function Get-OSDriveType {
    $DriveLetter = $env:windir
    $DriveLetter = $DriveLetter.Substring(0,1)
    $Partition = Get-Partition -DriveLetter $DriveLetter

    $DiskNumber = Get-Partition -DriveLetter $DriveLetter
    $DiskNumber = $DiskNumber.DiskNumber

    $PhysicalDisk = Get-PhysicalDisk -DeviceNumber $DiskNumber
    ########## Need to Add Check for Virtual Disk
    return $PhysicalDisk.BusType + " " + $PhysicalDisk.MediaType 
}

Export-ModuleMember -Function Get-MonitorInformation
Export-ModuleMember -Function Get-DocumentScanners
Export-ModuleMember -Function Get-USBAudio
Export-ModuleMember -Function Get-USBCameras
Export-ModuleMember -Function Get-USBPrinters
Export-ModuleMember -Function Get-VideoDevices
Export-ModuleMember -Function Get-RAMGBsInstalled
Export-ModuleMember -Function Get-RAMSlots
Export-ModuleMember -Function Get-InstalledApplications
Export-ModuleMember -Function Get-RealNetworkAdapters
Export-ModuleMember -Function Get-ProcessorName
Export-ModuleMember -Function Get-EnclosureType
Export-ModuleMember -Function Get-OSDriveType

### ### ### ======================================================================
### ### ### PERFORMANCE FUNCTIONS
### ### ### ======================================================================

Function Get-CPUScore {

    <#
    .SYNOPSIS
        Returns CPU score as benchmarked by cpubenchmark.net
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
     
        NOTES
            This can be used to help determine if a slow computer is a hardware issue.
            Performance within the same CPU model can vary 5-10%, or even 20% in extreme cases.
            This can also be used to generate lists for clients of their slowest PCs and what might need replaced soon.
 
        TIPS
            This is generally a strong indicator of whether a PC will need replaced, but NOT a definitive indicator.
            I will usually tell a client that CPUs with a score of <5000 very likely impacting employee productivity.
            Here is a Microsoft PowerPoint presentation noting that slow PCs can cause thousands of dollars in productivity loss:
            https://news.microsoft.com/wp-content/uploads/prod/sites/433/2018/10/Pan-Asia-W7-EOS-Media-Presentation-Deck.pdf
 
    .EXAMPLE
        Get-CPUScore
 
        Returns the CPU's score as benchmarked by cpubenchmark.net.
 
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    $ProcessorName = New-Object 'string[]' 1000
    $ProcessorScore = New-Object 'string[]' 1000

    $WorkstationProcessorName = Get-WMIObject win32_Processor | select name
    $WorkstationProcessorName = $WorkstationProcessorName.Name
    $WorkstationProcessorScore = "Unknown"

    $ProcessorName[0] = "i3-1000NG4 ";      $ProcessorScore[0] = "4326"
    $ProcessorName[1] = "i3-1005G1 ";      $ProcessorScore[1] = "5257"
    $ProcessorName[2] = "i3-10100 ";      $ProcessorScore[2] = "8865"
    $ProcessorName[3] = "i3-10100T ";      $ProcessorScore[3] = "7589"
    $ProcessorName[4] = "i3-10110U ";      $ProcessorScore[4] = "4076"
    $ProcessorName[5] = "i3-10110Y ";      $ProcessorScore[5] = "3639"
    $ProcessorName[6] = "i3-10300 ";      $ProcessorScore[6] = "9256"
    $ProcessorName[7] = "i3-10300T ";      $ProcessorScore[7] = "8355"
    $ProcessorName[8] = "i3-2100 ";      $ProcessorScore[8] = "1781"
    $ProcessorName[9] = "i3-2100T ";      $ProcessorScore[9] = "1694"
    $ProcessorName[10] = "i3-2102 ";      $ProcessorScore[10] = "2029"
    $ProcessorName[11] = "i3-2105 ";      $ProcessorScore[11] = "1814"
    $ProcessorName[12] = "i3-21050 ";      $ProcessorScore[12] = "2193"
    $ProcessorName[13] = "i3-2120 ";      $ProcessorScore[13] = "1901"
    $ProcessorName[14] = "i3-2120T ";      $ProcessorScore[14] = "1436"
    $ProcessorName[15] = "i3-2125 ";      $ProcessorScore[15] = "2167"
    $ProcessorName[16] = "i3-2130 ";      $ProcessorScore[16] = "1984"
    $ProcessorName[17] = "i3-2140 ";      $ProcessorScore[17] = "2456"
    $ProcessorName[18] = "i3-2310E ";      $ProcessorScore[18] = "1845"
    $ProcessorName[19] = "i3-2310M ";      $ProcessorScore[19] = "1169"
    $ProcessorName[20] = "i3-2312M ";      $ProcessorScore[20] = "1369"
    $ProcessorName[21] = "i3-2328M ";      $ProcessorScore[21] = "1217"
    $ProcessorName[22] = "i3-2330E ";      $ProcessorScore[22] = "1823"
    $ProcessorName[23] = "i3-2330M ";      $ProcessorScore[23] = "1226"
    $ProcessorName[24] = "i3-2332M ";      $ProcessorScore[24] = "1353"
    $ProcessorName[25] = "i3-2340UE ";      $ProcessorScore[25] = "976"
    $ProcessorName[26] = "i3-2348M ";      $ProcessorScore[26] = "1221"
    $ProcessorName[27] = "i3-2350M ";      $ProcessorScore[27] = "1204"
    $ProcessorName[28] = "i3-2357M ";      $ProcessorScore[28] = "866"
    $ProcessorName[29] = "i3-2365M ";      $ProcessorScore[29] = "864"
    $ProcessorName[30] = "i3-2367M ";      $ProcessorScore[30] = "933"
    $ProcessorName[31] = "i3-2370M ";      $ProcessorScore[31] = "1276"
    $ProcessorName[32] = "i3-2375M ";      $ProcessorScore[32] = "929"
    $ProcessorName[33] = "i3-2377M ";      $ProcessorScore[33] = "861"
    $ProcessorName[34] = "i3-3110M ";      $ProcessorScore[34] = "1568"
    $ProcessorName[35] = "i3-3120M ";      $ProcessorScore[35] = "1638"
    $ProcessorName[36] = "i3-3130M ";      $ProcessorScore[36] = "1824"
    $ProcessorName[37] = "i3-3210 ";      $ProcessorScore[37] = "2036"
    $ProcessorName[38] = "i3-3217U ";      $ProcessorScore[38] = "1177"
    $ProcessorName[39] = "i3-3217UE ";      $ProcessorScore[39] = "1362"
    $ProcessorName[40] = "i3-3220 ";      $ProcessorScore[40] = "2200"
    $ProcessorName[41] = "i3-3220T ";      $ProcessorScore[41] = "1991"
    $ProcessorName[42] = "i3-3225 ";      $ProcessorScore[42] = "2174"
    $ProcessorName[43] = "i3-3227U ";      $ProcessorScore[43] = "1285"
    $ProcessorName[44] = "i3-3229Y ";      $ProcessorScore[44] = "1236"
    $ProcessorName[45] = "i3-3240 ";      $ProcessorScore[45] = "2274"
    $ProcessorName[46] = "i3-3240T ";      $ProcessorScore[46] = "1981"
    $ProcessorName[47] = "i3-3245 ";      $ProcessorScore[47] = "2643"
    $ProcessorName[48] = "i3-3250 ";      $ProcessorScore[48] = "2331"
    $ProcessorName[49] = "i3-3250T ";      $ProcessorScore[49] = "2650"
    $ProcessorName[50] = "i3-330E ";      $ProcessorScore[50] = "1260"
    $ProcessorName[51] = "i3-330M ";      $ProcessorScore[51] = "971"
    $ProcessorName[52] = "i3-330UM ";      $ProcessorScore[52] = "666"
    $ProcessorName[53] = "i3-350M ";      $ProcessorScore[53] = "1056"
    $ProcessorName[54] = "i3-370M ";      $ProcessorScore[54] = "1128"
    $ProcessorName[55] = "i3-380M ";      $ProcessorScore[55] = "1124"
    $ProcessorName[56] = "i3-380UM ";      $ProcessorScore[56] = "708"
    $ProcessorName[57] = "i3-390M ";      $ProcessorScore[57] = "1231"
    $ProcessorName[58] = "i3-4000M ";      $ProcessorScore[58] = "1692"
    $ProcessorName[59] = "i3-4005U ";      $ProcessorScore[59] = "1666"
    $ProcessorName[60] = "i3-4010U ";      $ProcessorScore[60] = "1672"
    $ProcessorName[61] = "i3-4010Y ";      $ProcessorScore[61] = "1310"
    $ProcessorName[62] = "i3-4012Y ";      $ProcessorScore[62] = "1256"
    $ProcessorName[63] = "i3-4020Y ";      $ProcessorScore[63] = "1437"
    $ProcessorName[64] = "i3-4025U ";      $ProcessorScore[64] = "1918"
    $ProcessorName[65] = "i3-4030U ";      $ProcessorScore[65] = "1871"
    $ProcessorName[66] = "i3-4030Y ";      $ProcessorScore[66] = "1623"
    $ProcessorName[67] = "i3-4100M ";      $ProcessorScore[67] = "2362"
    $ProcessorName[68] = "i3-4110M ";      $ProcessorScore[68] = "2580"
    $ProcessorName[69] = "i3-4110U ";      $ProcessorScore[69] = "1853"
    $ProcessorName[70] = "i3-4120U ";      $ProcessorScore[70] = "1948"
    $ProcessorName[71] = "i3-4130 ";      $ProcessorScore[71] = "3266"
    $ProcessorName[72] = "i3-4130T ";      $ProcessorScore[72] = "2848"
    $ProcessorName[73] = "i3-4150 ";      $ProcessorScore[73] = "3375"
    $ProcessorName[74] = "i3-4150T ";      $ProcessorScore[74] = "2726"
    $ProcessorName[75] = "i3-4158U ";      $ProcessorScore[75] = "1718"
    $ProcessorName[76] = "i3-4160 ";      $ProcessorScore[76] = "3474"
    $ProcessorName[77] = "i3-4160T ";      $ProcessorScore[77] = "3086"
    $ProcessorName[78] = "i3-4170 ";      $ProcessorScore[78] = "3596"
    $ProcessorName[79] = "i3-4170T ";      $ProcessorScore[79] = "3177"
    $ProcessorName[80] = "i3-4330 ";      $ProcessorScore[80] = "3576"
    $ProcessorName[81] = "i3-4330T ";      $ProcessorScore[81] = "3098"
    $ProcessorName[82] = "i3-4330TE ";      $ProcessorScore[82] = "2500"
    $ProcessorName[83] = "i3-4340 ";      $ProcessorScore[83] = "3528"
    $ProcessorName[84] = "i3-4350 ";      $ProcessorScore[84] = "3163"
    $ProcessorName[85] = "i3-4350T ";      $ProcessorScore[85] = "2888"
    $ProcessorName[86] = "i3-4360 ";      $ProcessorScore[86] = "3577"
    $ProcessorName[87] = "i3-4360T ";      $ProcessorScore[87] = "3164"
    $ProcessorName[88] = "i3-4370 ";      $ProcessorScore[88] = "3851"
    $ProcessorName[89] = "i3-4370T ";      $ProcessorScore[89] = "3187"
    $ProcessorName[90] = "i3-4570T ";      $ProcessorScore[90] = "3244"
    $ProcessorName[91] = "i3-5005U ";      $ProcessorScore[91] = "2039"
    $ProcessorName[92] = "i3-5010U ";      $ProcessorScore[92] = "2161"
    $ProcessorName[93] = "i3-5015U ";      $ProcessorScore[93] = "2047"
    $ProcessorName[94] = "i3-5020U ";      $ProcessorScore[94] = "2222"
    $ProcessorName[95] = "i3-5157U ";      $ProcessorScore[95] = "2613"
    $ProcessorName[96] = "i3-530 ";      $ProcessorScore[96] = "1437"
    $ProcessorName[97] = "i3-540 ";      $ProcessorScore[97] = "1505"
    $ProcessorName[98] = "i3-550 ";      $ProcessorScore[98] = "1553"
    $ProcessorName[99] = "i3-560 ";      $ProcessorScore[99] = "1626"
    $ProcessorName[100] = "i3-6006U ";      $ProcessorScore[100] = "2288"
    $ProcessorName[101] = "i3-6098P ";      $ProcessorScore[101] = "4127"
    $ProcessorName[102] = "i3-6100 ";      $ProcessorScore[102] = "4153"
    $ProcessorName[103] = "i3-6100E ";      $ProcessorScore[103] = "3315"
    $ProcessorName[104] = "i3-6100H ";      $ProcessorScore[104] = "3191"
    $ProcessorName[105] = "i3-6100T ";      $ProcessorScore[105] = "3660"
    $ProcessorName[106] = "i3-6100TE ";      $ProcessorScore[106] = "3354"
    $ProcessorName[107] = "i3-6100U ";      $ProcessorScore[107] = "2623"
    $ProcessorName[108] = "i3-6102E ";      $ProcessorScore[108] = "2349"
    $ProcessorName[109] = "i3-6157U ";      $ProcessorScore[109] = "2758"
    $ProcessorName[110] = "i3-6300 ";      $ProcessorScore[110] = "4464"
    $ProcessorName[111] = "i3-6300T ";      $ProcessorScore[111] = "4040"
    $ProcessorName[112] = "i3-6320 ";      $ProcessorScore[112] = "4419"
    $ProcessorName[113] = "i3-7020U ";      $ProcessorScore[113] = "2557"
    $ProcessorName[114] = "i3-7100 ";      $ProcessorScore[114] = "4290"
    $ProcessorName[115] = "i3-7100H ";      $ProcessorScore[115] = "3460"
    $ProcessorName[116] = "i3-7100T ";      $ProcessorScore[116] = "3795"
    $ProcessorName[117] = "i3-7100U ";      $ProcessorScore[117] = "2724"
    $ProcessorName[118] = "i3-7101TE ";      $ProcessorScore[118] = "4003"
    $ProcessorName[119] = "i3-7102E ";      $ProcessorScore[119] = "2521"
    $ProcessorName[120] = "i3-7130U ";      $ProcessorScore[120] = "2995"
    $ProcessorName[121] = "i3-7167U ";      $ProcessorScore[121] = "3489"
    $ProcessorName[122] = "i3-7300 ";      $ProcessorScore[122] = "4778"
    $ProcessorName[123] = "i3-7300T ";      $ProcessorScore[123] = "4181"
    $ProcessorName[124] = "i3-7320 ";      $ProcessorScore[124] = "4862"
    $ProcessorName[125] = "i3-7350K ";      $ProcessorScore[125] = "4804"
    $ProcessorName[126] = "i3-8100 ";      $ProcessorScore[126] = "6153"
    $ProcessorName[127] = "i3-8100B ";      $ProcessorScore[127] = "6829"
    $ProcessorName[128] = "i3-8100T ";      $ProcessorScore[128] = "5293"
    $ProcessorName[129] = "i3-8109U ";      $ProcessorScore[129] = "4383"
    $ProcessorName[130] = "i3-8121U ";      $ProcessorScore[130] = "4340"
    $ProcessorName[131] = "i3-8130U ";      $ProcessorScore[131] = "3660"
    $ProcessorName[132] = "i3-8145U ";      $ProcessorScore[132] = "3727"
    $ProcessorName[133] = "i3-8145UE ";      $ProcessorScore[133] = "4140"
    $ProcessorName[134] = "i3-8300 ";      $ProcessorScore[134] = "6317"
    $ProcessorName[135] = "i3-8300T ";      $ProcessorScore[135] = "5827"
    $ProcessorName[136] = "i3-8350K ";      $ProcessorScore[136] = "7009"
    $ProcessorName[137] = "i3-9100 ";      $ProcessorScore[137] = "6667"
    $ProcessorName[138] = "i3-9100F ";      $ProcessorScore[138] = "6835"
    $ProcessorName[139] = "i3-9100T ";      $ProcessorScore[139] = "5623"
    $ProcessorName[140] = "i3-9300 ";      $ProcessorScore[140] = "7267"
    $ProcessorName[141] = "i3-9300T ";      $ProcessorScore[141] = "6367"
    $ProcessorName[142] = "i3-9320 ";      $ProcessorScore[142] = "7358"
    $ProcessorName[143] = "i3-9350K ";      $ProcessorScore[143] = "7759"
    $ProcessorName[144] = "i3-9350KF ";      $ProcessorScore[144] = "7913"
    $ProcessorName[145] = "i5-10210U ";      $ProcessorScore[145] = "6487"
    $ProcessorName[146] = "i5-10210Y ";      $ProcessorScore[146] = "4918"
    $ProcessorName[147] = "i5-10300H ";      $ProcessorScore[147] = "8913"
    $ProcessorName[148] = "i5-1030NG7 ";      $ProcessorScore[148] = "5331"
    $ProcessorName[149] = "i5-10310U ";      $ProcessorScore[149] = "6788"
    $ProcessorName[150] = "i5-1035G1 ";      $ProcessorScore[150] = "7977"
    $ProcessorName[151] = "i5-1035G4 ";      $ProcessorScore[151] = "8211"
    $ProcessorName[152] = "i5-1035G7 ";      $ProcessorScore[152] = "8495"
    $ProcessorName[153] = "i5-1038NG7 ";      $ProcessorScore[153] = "9907"
    $ProcessorName[154] = "i5-10400 ";      $ProcessorScore[154] = "12715"
    $ProcessorName[155] = "i5-10400F ";      $ProcessorScore[155] = "12704"
    $ProcessorName[156] = "i5-10400H ";      $ProcessorScore[156] = "8911"
    $ProcessorName[157] = "i5-10400T ";      $ProcessorScore[157] = "10429"
    $ProcessorName[158] = "i5-10500 ";      $ProcessorScore[158] = "13419"
    $ProcessorName[159] = "i5-10500T ";      $ProcessorScore[159] = "10802"
    $ProcessorName[160] = "i5-10600 ";      $ProcessorScore[160] = "14069"
    $ProcessorName[161] = "i5-10600K ";      $ProcessorScore[161] = "14577"
    $ProcessorName[162] = "i5-10600KF ";      $ProcessorScore[162] = "14900"
    $ProcessorName[163] = "i5-10600T ";      $ProcessorScore[163] = "11330"
    $ProcessorName[164] = "i5-1135G7 ";      $ProcessorScore[164] = "10537"
    $ProcessorName[165] = "i5-2300 ";      $ProcessorScore[165] = "3343"
    $ProcessorName[166] = "i5-2310 ";      $ProcessorScore[166] = "3435"
    $ProcessorName[167] = "i5-2320 ";      $ProcessorScore[167] = "3595"
    $ProcessorName[168] = "i5-2380P ";      $ProcessorScore[168] = "3709"
    $ProcessorName[169] = "i5-2390T ";      $ProcessorScore[169] = "2310"
    $ProcessorName[170] = "i5-2400 ";      $ProcessorScore[170] = "3795"
    $ProcessorName[171] = "i5-2400S ";      $ProcessorScore[171] = "3140"
    $ProcessorName[172] = "i5-24050S ";      $ProcessorScore[172] = "2799"
    $ProcessorName[173] = "i5-2405S ";      $ProcessorScore[173] = "2980"
    $ProcessorName[174] = "i5-2410M ";      $ProcessorScore[174] = "1920"
    $ProcessorName[175] = "i5-2415M ";      $ProcessorScore[175] = "2035"
    $ProcessorName[176] = "i5-2430M ";      $ProcessorScore[176] = "1963"
    $ProcessorName[177] = "i5-2435M ";      $ProcessorScore[177] = "1738"
    $ProcessorName[178] = "i5-2450M ";      $ProcessorScore[178] = "2053"
    $ProcessorName[179] = "i5-2450P ";      $ProcessorScore[179] = "3869"
    $ProcessorName[180] = "i5-2467M ";      $ProcessorScore[180] = "1611"
    $ProcessorName[181] = "i5-2500 ";      $ProcessorScore[181] = "4061"
    $ProcessorName[182] = "i5-2500K ";      $ProcessorScore[182] = "4087"
    $ProcessorName[183] = "i5-2500S ";      $ProcessorScore[183] = "3318"
    $ProcessorName[184] = "i5-2500T ";      $ProcessorScore[184] = "2741"
    $ProcessorName[185] = "i5-2510E ";      $ProcessorScore[185] = "1889"
    $ProcessorName[186] = "i5-2515E ";      $ProcessorScore[186] = "1882"
    $ProcessorName[187] = "i5-2520M ";      $ProcessorScore[187] = "2307"
    $ProcessorName[188] = "i5-2537M ";      $ProcessorScore[188] = "1094"
    $ProcessorName[189] = "i5-2540M ";      $ProcessorScore[189] = "2281"
    $ProcessorName[190] = "i5-2550K ";      $ProcessorScore[190] = "4105"
    $ProcessorName[191] = "i5-2557M ";      $ProcessorScore[191] = "1628"
    $ProcessorName[192] = "i5-2560M ";      $ProcessorScore[192] = "2131"
    $ProcessorName[193] = "i5-3170K ";      $ProcessorScore[193] = "8882"
    $ProcessorName[194] = "i5-3210M ";      $ProcessorScore[194] = "2438"
    $ProcessorName[195] = "i5-3230M ";      $ProcessorScore[195] = "2516"
    $ProcessorName[196] = "i5-3317U ";      $ProcessorScore[196] = "1954"
    $ProcessorName[197] = "i5-3320M ";      $ProcessorScore[197] = "2645"
    $ProcessorName[198] = "i5-3330 ";      $ProcessorScore[198] = "4089"
    $ProcessorName[199] = "i5-3330S ";      $ProcessorScore[199] = "3856"
    $ProcessorName[200] = "i5-3335S ";      $ProcessorScore[200] = "3754"
    $ProcessorName[201] = "i5-3337U ";      $ProcessorScore[201] = "2164"
    $ProcessorName[202] = "i5-3339Y ";      $ProcessorScore[202] = "1499"
    $ProcessorName[203] = "i5-3340 ";      $ProcessorScore[203] = "4281"
    $ProcessorName[204] = "i5-3340M ";      $ProcessorScore[204] = "2732"
    $ProcessorName[205] = "i5-3340S ";      $ProcessorScore[205] = "3876"
    $ProcessorName[206] = "i5-3350P ";      $ProcessorScore[206] = "4283"
    $ProcessorName[207] = "i5-3360M ";      $ProcessorScore[207] = "2955"
    $ProcessorName[208] = "i5-3380M ";      $ProcessorScore[208] = "3015"
    $ProcessorName[209] = "i5-3427U ";      $ProcessorScore[209] = "2275"
    $ProcessorName[210] = "i5-3437U ";      $ProcessorScore[210] = "2205"
    $ProcessorName[211] = "i5-3439Y ";      $ProcessorScore[211] = "1907"
    $ProcessorName[212] = "i5-3450 ";      $ProcessorScore[212] = "4396"
    $ProcessorName[213] = "i5-3450S ";      $ProcessorScore[213] = "4154"
    $ProcessorName[214] = "i5-3470 ";      $ProcessorScore[214] = "4645"
    $ProcessorName[215] = "i5-3470S ";      $ProcessorScore[215] = "4338"
    $ProcessorName[216] = "i5-3470T ";      $ProcessorScore[216] = "2978"
    $ProcessorName[217] = "i5-3475S ";      $ProcessorScore[217] = "4073"
    $ProcessorName[218] = "i5-3550 ";      $ProcessorScore[218] = "4801"
    $ProcessorName[219] = "i5-3550S ";      $ProcessorScore[219] = "4422"
    $ProcessorName[220] = "i5-3570 ";      $ProcessorScore[220] = "4894"
    $ProcessorName[221] = "i5-3570K ";      $ProcessorScore[221] = "4929"
    $ProcessorName[222] = "i5-3570S ";      $ProcessorScore[222] = "4615"
    $ProcessorName[223] = "i5-3570T ";      $ProcessorScore[223] = "4120"
    $ProcessorName[224] = "i5-3610ME ";      $ProcessorScore[224] = "2623"
    $ProcessorName[225] = "i5-4200H ";      $ProcessorScore[225] = "3079"
    $ProcessorName[226] = "i5-4200M ";      $ProcessorScore[226] = "2834"
    $ProcessorName[227] = "i5-4200U ";      $ProcessorScore[227] = "2172"
    $ProcessorName[228] = "i5-4200Y ";      $ProcessorScore[228] = "1558"
    $ProcessorName[229] = "i5-4202Y ";      $ProcessorScore[229] = "1606"
    $ProcessorName[230] = "i5-4210H ";      $ProcessorScore[230] = "2786"
    $ProcessorName[231] = "i5-4210M ";      $ProcessorScore[231] = "2876"
    $ProcessorName[232] = "i5-4210U ";      $ProcessorScore[232] = "2270"
    $ProcessorName[233] = "i5-4210Y ";      $ProcessorScore[233] = "1651"
    $ProcessorName[234] = "i5-4220Y ";      $ProcessorScore[234] = "1400"
    $ProcessorName[235] = "i5-4230U ";      $ProcessorScore[235] = "1853"
    $ProcessorName[236] = "i5-4250U ";      $ProcessorScore[236] = "2137"
    $ProcessorName[237] = "i5-4258U ";      $ProcessorScore[237] = "2713"
    $ProcessorName[238] = "i5-4260U ";      $ProcessorScore[238] = "2480"
    $ProcessorName[239] = "i5-4278U ";      $ProcessorScore[239] = "2948"
    $ProcessorName[240] = "i5-4288U ";      $ProcessorScore[240] = "2317"
    $ProcessorName[241] = "i5-4300M ";      $ProcessorScore[241] = "3042"
    $ProcessorName[242] = "i5-4300U ";      $ProcessorScore[242] = "2503"
    $ProcessorName[243] = "i5-4300Y ";      $ProcessorScore[243] = "1531"
    $ProcessorName[244] = "i5-4302Y ";      $ProcessorScore[244] = "1817"
    $ProcessorName[245] = "i5-4308U ";      $ProcessorScore[245] = "2854"
    $ProcessorName[246] = "i5-430M ";      $ProcessorScore[246] = "1216"
    $ProcessorName[247] = "i5-430UM ";      $ProcessorScore[247] = "836"
    $ProcessorName[248] = "i5-4310M ";      $ProcessorScore[248] = "3206"
    $ProcessorName[249] = "i5-4310U ";      $ProcessorScore[249] = "2505"
    $ProcessorName[250] = "i5-4330M ";      $ProcessorScore[250] = "3217"
    $ProcessorName[251] = "i5-4340M ";      $ProcessorScore[251] = "3398"
    $ProcessorName[252] = "i5-4350U ";      $ProcessorScore[252] = "2305"
    $ProcessorName[253] = "i5-4400E ";      $ProcessorScore[253] = "3251"
    $ProcessorName[254] = "i5-4402E ";      $ProcessorScore[254] = "2681"
    $ProcessorName[255] = "i5-4422E ";      $ProcessorScore[255] = "1907"
    $ProcessorName[256] = "i5-4430 ";      $ProcessorScore[256] = "4713"
    $ProcessorName[257] = "i5-4430S ";      $ProcessorScore[257] = "4332"
    $ProcessorName[258] = "i5-4440 ";      $ProcessorScore[258] = "4662"
    $ProcessorName[259] = "i5-4440S ";      $ProcessorScore[259] = "4010"
    $ProcessorName[260] = "i5-4460 ";      $ProcessorScore[260] = "4791"
    $ProcessorName[261] = "i5-4460S ";      $ProcessorScore[261] = "4445"
    $ProcessorName[262] = "i5-4460T ";      $ProcessorScore[262] = "3583"
    $ProcessorName[263] = "i5-4470S ";      $ProcessorScore[263] = "4742"
    $ProcessorName[264] = "i5-450M ";      $ProcessorScore[264] = "1226"
    $ProcessorName[265] = "i5-4570 ";      $ProcessorScore[265] = "5159"
    $ProcessorName[266] = "i5-4570R ";      $ProcessorScore[266] = "4820"
    $ProcessorName[267] = "i5-4570S ";      $ProcessorScore[267] = "5000"
    $ProcessorName[268] = "i5-4570T ";      $ProcessorScore[268] = "3256"
    $ProcessorName[269] = "i5-4570TE ";      $ProcessorScore[269] = "3043"
    $ProcessorName[270] = "i5-4590 ";      $ProcessorScore[270] = "5298"
    $ProcessorName[271] = "i5-4590S ";      $ProcessorScore[271] = "5083"
    $ProcessorName[272] = "i5-4590T ";      $ProcessorScore[272] = "3969"
    $ProcessorName[273] = "i5-460M ";      $ProcessorScore[273] = "1288"
    $ProcessorName[274] = "i5-4670 ";      $ProcessorScore[274] = "5452"
    $ProcessorName[275] = "i5-4670K ";      $ProcessorScore[275] = "5510"
    $ProcessorName[276] = "i5-4670K CPT ";      $ProcessorScore[276] = "5034"
    $ProcessorName[277] = "i5-4670R ";      $ProcessorScore[277] = "5335"
    $ProcessorName[278] = "i5-4670S ";      $ProcessorScore[278] = "4985"
    $ProcessorName[279] = "i5-4670T ";      $ProcessorScore[279] = "4404"
    $ProcessorName[280] = "i5-4690 ";      $ProcessorScore[280] = "5601"
    $ProcessorName[281] = "i5-4690K ";      $ProcessorScore[281] = "5545"
    $ProcessorName[282] = "i5-4690S ";      $ProcessorScore[282] = "5270"
    $ProcessorName[283] = "i5-4690T ";      $ProcessorScore[283] = "4267"
    $ProcessorName[284] = "i5-470UM ";      $ProcessorScore[284] = "752"
    $ProcessorName[285] = "i5-480M ";      $ProcessorScore[285] = "1305"
    $ProcessorName[286] = "i5-5200U ";      $ProcessorScore[286] = "2493"
    $ProcessorName[287] = "i5-520M ";      $ProcessorScore[287] = "1696"
    $ProcessorName[288] = "i5-520UM ";      $ProcessorScore[288] = "928"
    $ProcessorName[289] = "i5-5250U ";      $ProcessorScore[289] = "2458"
    $ProcessorName[290] = "i5-5257U ";      $ProcessorScore[290] = "2953"
    $ProcessorName[291] = "i5-5287U ";      $ProcessorScore[291] = "3356"
    $ProcessorName[292] = "i5-5300U ";      $ProcessorScore[292] = "2742"
    $ProcessorName[293] = "i5-5350U ";      $ProcessorScore[293] = "2667"
    $ProcessorName[294] = "i5-540M ";      $ProcessorScore[294] = "1753"
    $ProcessorName[295] = "i5-540UM ";      $ProcessorScore[295] = "1002"
    $ProcessorName[296] = "i5-5575R ";      $ProcessorScore[296] = "5550"
    $ProcessorName[297] = "i5-560M ";      $ProcessorScore[297] = "1830"
    $ProcessorName[298] = "i5-560UM ";      $ProcessorScore[298] = "1015"
    $ProcessorName[299] = "i5-5675C ";      $ProcessorScore[299] = "5932"
    $ProcessorName[300] = "i5-5675R ";      $ProcessorScore[300] = "5931"
    $ProcessorName[301] = "i5-580M ";      $ProcessorScore[301] = "1922"
    $ProcessorName[302] = "i5-6198DU ";      $ProcessorScore[302] = "3138"
    $ProcessorName[303] = "i5-6200U ";      $ProcessorScore[303] = "3021"
    $ProcessorName[304] = "i5-6260U ";      $ProcessorScore[304] = "3198"
    $ProcessorName[305] = "i5-6267U ";      $ProcessorScore[305] = "3124"
    $ProcessorName[306] = "i5-6287U ";      $ProcessorScore[306] = "3655"
    $ProcessorName[307] = "i5-6300HQ ";      $ProcessorScore[307] = "4625"
    $ProcessorName[308] = "i5-6300U ";      $ProcessorScore[308] = "3252"
    $ProcessorName[309] = "i5-6360U ";      $ProcessorScore[309] = "3259"
    $ProcessorName[310] = "i5-6400 ";      $ProcessorScore[310] = "5151"
    $ProcessorName[311] = "i5-6400T ";      $ProcessorScore[311] = "4396"
    $ProcessorName[312] = "i5-6402P ";      $ProcessorScore[312] = "5703"
    $ProcessorName[313] = "i5-6440EQ ";      $ProcessorScore[313] = "5368"
    $ProcessorName[314] = "i5-6440HQ ";      $ProcessorScore[314] = "5305"
    $ProcessorName[315] = "i5-6442EQ ";      $ProcessorScore[315] = "4519"
    $ProcessorName[316] = "i5-650 ";      $ProcessorScore[316] = "2200"
    $ProcessorName[317] = "i5-6500 ";      $ProcessorScore[317] = "5660"
    $ProcessorName[318] = "i5-6500T ";      $ProcessorScore[318] = "4977"
    $ProcessorName[319] = "i5-6500TE ";      $ProcessorScore[319] = "5295"
    $ProcessorName[320] = "i5-655K ";      $ProcessorScore[320] = "2017"
    $ProcessorName[321] = "i5-660 ";      $ProcessorScore[321] = "2331"
    $ProcessorName[322] = "i5-6600 ";      $ProcessorScore[322] = "6056"
    $ProcessorName[323] = "i5-6600K ";      $ProcessorScore[323] = "6287"
    $ProcessorName[324] = "i5-6600T ";      $ProcessorScore[324] = "5524"
    $ProcessorName[325] = "i5-661 ";      $ProcessorScore[325] = "2425"
    $ProcessorName[326] = "i5-670 ";      $ProcessorScore[326] = "2423"
    $ProcessorName[327] = "i5-680 ";      $ProcessorScore[327] = "2568"
    $ProcessorName[328] = "i5-7200U ";      $ProcessorScore[328] = "3391"
    $ProcessorName[329] = "i5-7260U ";      $ProcessorScore[329] = "3927"
    $ProcessorName[330] = "i5-7267U ";      $ProcessorScore[330] = "4093"
    $ProcessorName[331] = "i5-7287U ";      $ProcessorScore[331] = "4149"
    $ProcessorName[332] = "i5-7300HQ ";      $ProcessorScore[332] = "5107"
    $ProcessorName[333] = "i5-7300U ";      $ProcessorScore[333] = "3723"
    $ProcessorName[334] = "i5-7360U ";      $ProcessorScore[334] = "4334"
    $ProcessorName[335] = "i5-7400 ";      $ProcessorScore[335] = "5486"
    $ProcessorName[336] = "i5-7400T ";      $ProcessorScore[336] = "4556"
    $ProcessorName[337] = "i5-7440HQ ";      $ProcessorScore[337] = "5553"
    $ProcessorName[338] = "i5-7442EQ ";      $ProcessorScore[338] = "4834"
    $ProcessorName[339] = "i5-750 ";      $ProcessorScore[339] = "2431"
    $ProcessorName[340] = "i5-7500 ";      $ProcessorScore[340] = "6134"
    $ProcessorName[341] = "i5-7500T ";      $ProcessorScore[341] = "5356"
    $ProcessorName[342] = "i5-760 ";      $ProcessorScore[342] = "2559"
    $ProcessorName[343] = "i5-7600 ";      $ProcessorScore[343] = "6597"
    $ProcessorName[344] = "i5-7600K ";      $ProcessorScore[344] = "6855"
    $ProcessorName[345] = "i5-7600T ";      $ProcessorScore[345] = "5858"
    $ProcessorName[346] = "i5-760S ";      $ProcessorScore[346] = "5440"
    $ProcessorName[347] = "i5-7640X ";      $ProcessorScore[347] = "6467"
    $ProcessorName[348] = "i5-7Y54 ";      $ProcessorScore[348] = "2891"
    $ProcessorName[349] = "i5-7Y57 ";      $ProcessorScore[349] = "3070"
    $ProcessorName[350] = "i5-8200Y ";      $ProcessorScore[350] = "2308"
    $ProcessorName[351] = "i5-8210Y ";      $ProcessorScore[351] = "2905"
    $ProcessorName[352] = "i5-8250U ";      $ProcessorScore[352] = "6057"
    $ProcessorName[353] = "i5-8257U ";      $ProcessorScore[353] = "8182"
    $ProcessorName[354] = "i5-8259U ";      $ProcessorScore[354] = "8271"
    $ProcessorName[355] = "i5-8260U ";      $ProcessorScore[355] = "7776"
    $ProcessorName[356] = "i5-8265U ";      $ProcessorScore[356] = "6254"
    $ProcessorName[357] = "i5-8265UC ";      $ProcessorScore[357] = "5988"
    $ProcessorName[358] = "i5-8279U ";      $ProcessorScore[358] = "7917"
    $ProcessorName[359] = "i5-8300H ";      $ProcessorScore[359] = "7522"
    $ProcessorName[360] = "i5-8305G ";      $ProcessorScore[360] = "7073"
    $ProcessorName[361] = "i5-8350U ";      $ProcessorScore[361] = "6413"
    $ProcessorName[362] = "i5-8365U ";      $ProcessorScore[362] = "6422"
    $ProcessorName[363] = "i5-8365UE ";      $ProcessorScore[363] = "5243"
    $ProcessorName[364] = "i5-8400 ";      $ProcessorScore[364] = "9200"
    $ProcessorName[365] = "i5-8400H ";      $ProcessorScore[365] = "8146"
    $ProcessorName[366] = "i5-8400T ";      $ProcessorScore[366] = "7433"
    $ProcessorName[367] = "i5-8500 ";      $ProcessorScore[367] = "9486"
    $ProcessorName[368] = "i5-8500B ";      $ProcessorScore[368] = "9538"
    $ProcessorName[369] = "i5-8500T ";      $ProcessorScore[369] = "7881"
    $ProcessorName[370] = "i5-8600 ";      $ProcessorScore[370] = "9787"
    $ProcessorName[371] = "i5-8600K ";      $ProcessorScore[371] = "10266"
    $ProcessorName[372] = "i5-8600T ";      $ProcessorScore[372] = "8846"
    $ProcessorName[373] = "i5-9300H ";      $ProcessorScore[373] = "8008"
    $ProcessorName[374] = "i5-9300HF ";      $ProcessorScore[374] = "7742"
    $ProcessorName[375] = "i5-9400 ";      $ProcessorScore[375] = "9596"
    $ProcessorName[376] = "i5-9400F ";      $ProcessorScore[376] = "9597"
    $ProcessorName[377] = "i5-9400H ";      $ProcessorScore[377] = "8202"
    $ProcessorName[378] = "i5-9400T ";      $ProcessorScore[378] = "7819"
    $ProcessorName[379] = "i5-9500 ";      $ProcessorScore[379] = "9976"
    $ProcessorName[380] = "i5-9500F ";      $ProcessorScore[380] = "10342"
    $ProcessorName[381] = "i5-9500T ";      $ProcessorScore[381] = "8121"
    $ProcessorName[382] = "i5-9500TE ";      $ProcessorScore[382] = "9212"
    $ProcessorName[383] = "i5-9600 ";      $ProcessorScore[383] = "10741"
    $ProcessorName[384] = "i5-9600K ";      $ProcessorScore[384] = "10899"
    $ProcessorName[385] = "i5-9600KF ";      $ProcessorScore[385] = "10898"
    $ProcessorName[386] = "i5-9600T ";      $ProcessorScore[386] = "9406"
    $ProcessorName[387] = "i5-L16G7 ";      $ProcessorScore[387] = "3164"
    $ProcessorName[388] = "i7-10510U ";      $ProcessorScore[388] = "7072"
    $ProcessorName[389] = "i7-10510Y ";      $ProcessorScore[389] = "5523"
    $ProcessorName[390] = "i7-1060NG7 ";      $ProcessorScore[390] = "6234"
    $ProcessorName[391] = "i7-10610U ";      $ProcessorScore[391] = "7284"
    $ProcessorName[392] = "i7-1065G7 ";      $ProcessorScore[392] = "9005"
    $ProcessorName[393] = "i7-1068NG7 ";      $ProcessorScore[393] = "10689"
    $ProcessorName[394] = "i7-10700 ";      $ProcessorScore[394] = "17474"
    $ProcessorName[395] = "i7-10700F ";      $ProcessorScore[395] = "17251"
    $ProcessorName[396] = "i7-10700K ";      $ProcessorScore[396] = "19654"
    $ProcessorName[397] = "i7-10700KF ";      $ProcessorScore[397] = "19747"
    $ProcessorName[398] = "i7-10700T ";      $ProcessorScore[398] = "13344"
    $ProcessorName[399] = "i7-10710U ";      $ProcessorScore[399] = "10041"
    $ProcessorName[400] = "i9-10850K ";      $ProcessorScore[400] = "22535"
    $ProcessorName[401] = "i7-10750H ";      $ProcessorScore[401] = "12745"
    $ProcessorName[402] = "i7-10810U ";      $ProcessorScore[402] = "9100"
    $ProcessorName[403] = "i7-10850H ";      $ProcessorScore[403] = "13120"
    $ProcessorName[404] = "i7-10875H ";      $ProcessorScore[404] = "15996"
    $ProcessorName[405] = "i7-1165G7 ";      $ProcessorScore[405] = "12820"
    $ProcessorName[406] = "i7-1185G7 ";      $ProcessorScore[406] = "10354"
    $ProcessorName[407] = "i7-2600 ";      $ProcessorScore[407] = "5333"
    $ProcessorName[408] = "i7-2600K ";      $ProcessorScore[408] = "5428"
    $ProcessorName[409] = "i7-2600S ";      $ProcessorScore[409] = "4364"
    $ProcessorName[410] = "i7-2610UE ";      $ProcessorScore[410] = "1409"
    $ProcessorName[411] = "i7-2617M ";      $ProcessorScore[411] = "1687"
    $ProcessorName[412] = "i7-2620M ";      $ProcessorScore[412] = "2408"
    $ProcessorName[413] = "i7-2630QM ";      $ProcessorScore[413] = "3609"
    $ProcessorName[414] = "i7-2630UM ";      $ProcessorScore[414] = "400"
    $ProcessorName[415] = "i7-2635QM ";      $ProcessorScore[415] = "3232"
    $ProcessorName[416] = "i7-2637M ";      $ProcessorScore[416] = "1946"
    $ProcessorName[417] = "i7-2640M ";      $ProcessorScore[417] = "2442"
    $ProcessorName[418] = "i7-2655LE ";      $ProcessorScore[418] = "1928"
    $ProcessorName[419] = "i7-2670QM ";      $ProcessorScore[419] = "3739"
    $ProcessorName[420] = "i7-2675QM ";      $ProcessorScore[420] = "3168"
    $ProcessorName[421] = "i7-2677M ";      $ProcessorScore[421] = "1799"
    $ProcessorName[422] = "i7-2700K ";      $ProcessorScore[422] = "5471"
    $ProcessorName[423] = "i7-2710QE ";      $ProcessorScore[423] = "3704"
    $ProcessorName[424] = "i7-2715QE ";      $ProcessorScore[424] = "3221"
    $ProcessorName[425] = "i7-2720QM ";      $ProcessorScore[425] = "4072"
    $ProcessorName[426] = "i7-2760QM ";      $ProcessorScore[426] = "4304"
    $ProcessorName[427] = "i7-2820QM ";      $ProcessorScore[427] = "4195"
    $ProcessorName[428] = "i7-2840QM ";      $ProcessorScore[428] = "3842"
    $ProcessorName[429] = "i7-2860QM ";      $ProcessorScore[429] = "4526"
    $ProcessorName[430] = "i7-2920XM ";      $ProcessorScore[430] = "4512"
    $ProcessorName[431] = "i7-2960XM ";      $ProcessorScore[431] = "3985"
    $ProcessorName[432] = "i7-3517U ";      $ProcessorScore[432] = "2170"
    $ProcessorName[433] = "i7-3517UE ";      $ProcessorScore[433] = "2141"
    $ProcessorName[434] = "i7-3520M ";      $ProcessorScore[434] = "2860"
    $ProcessorName[435] = "i7-3537U ";      $ProcessorScore[435] = "2402"
    $ProcessorName[436] = "i7-3540M ";      $ProcessorScore[436] = "2921"
    $ProcessorName[437] = "i7-3555LE ";      $ProcessorScore[437] = "1880"
    $ProcessorName[438] = "i7-3610QE ";      $ProcessorScore[438] = "4730"
    $ProcessorName[439] = "i7-3610QM ";      $ProcessorScore[439] = "5139"
    $ProcessorName[440] = "i7-3612QE ";      $ProcessorScore[440] = "4783"
    $ProcessorName[441] = "i7-3612QM ";      $ProcessorScore[441] = "4403"
    $ProcessorName[442] = "i7-3615QE ";      $ProcessorScore[442] = "5174"
    $ProcessorName[443] = "i7-3615QM ";      $ProcessorScore[443] = "4913"
    $ProcessorName[444] = "i7-3630QM ";      $ProcessorScore[444] = "5069"
    $ProcessorName[445] = "i7-3632QM ";      $ProcessorScore[445] = "4449"
    $ProcessorName[446] = "i7-3635QM ";      $ProcessorScore[446] = "4527"
    $ProcessorName[447] = "i7-3667U ";      $ProcessorScore[447] = "2515"
    $ProcessorName[448] = "i7-3687U ";      $ProcessorScore[448] = "2592"
    $ProcessorName[449] = "i7-3689Y ";      $ProcessorScore[449] = "1642"
    $ProcessorName[450] = "i7-3720QM ";      $ProcessorScore[450] = "5633"
    $ProcessorName[451] = "i7-3740QM ";      $ProcessorScore[451] = "5648"
    $ProcessorName[452] = "i7-3770 ";      $ProcessorScore[452] = "6370"
    $ProcessorName[453] = "i7-3770K ";      $ProcessorScore[453] = "6459"
    $ProcessorName[454] = "i7-3770S ";      $ProcessorScore[454] = "6241"
    $ProcessorName[455] = "i7-3770T ";      $ProcessorScore[455] = "5511"
    $ProcessorName[456] = "i7-3820 ";      $ProcessorScore[456] = "5863"
    $ProcessorName[457] = "i7-3820QM ";      $ProcessorScore[457] = "5608"
    $ProcessorName[458] = "i7-3840QM ";      $ProcessorScore[458] = "5983"
    $ProcessorName[459] = "i7-3920XM ";      $ProcessorScore[459] = "6001"
    $ProcessorName[460] = "i7-3930K ";      $ProcessorScore[460] = "8147"
    $ProcessorName[461] = "i7-3940XM ";      $ProcessorScore[461] = "5320"
    $ProcessorName[462] = "i7-3960X ";      $ProcessorScore[462] = "8672"
    $ProcessorName[463] = "i7-3970X ";      $ProcessorScore[463] = "8490"
    $ProcessorName[464] = "i7-4500U ";      $ProcessorScore[464] = "2532"
    $ProcessorName[465] = "i7-4510U ";      $ProcessorScore[465] = "2607"
    $ProcessorName[466] = "i7-4550U ";      $ProcessorScore[466] = "2131"
    $ProcessorName[467] = "i7-4558U ";      $ProcessorScore[467] = "2999"
    $ProcessorName[468] = "i7-4560U ";      $ProcessorScore[468] = "2950"
    $ProcessorName[469] = "i7-4578U ";      $ProcessorScore[469] = "3258"
    $ProcessorName[470] = "i7-4600M ";      $ProcessorScore[470] = "3181"
    $ProcessorName[471] = "i7-4600U ";      $ProcessorScore[471] = "2683"
    $ProcessorName[472] = "i7-4610M ";      $ProcessorScore[472] = "3249"
    $ProcessorName[473] = "i7-4610Y ";      $ProcessorScore[473] = "2446"
    $ProcessorName[474] = "i7-4650U ";      $ProcessorScore[474] = "2247"
    $ProcessorName[475] = "i7-4700EQ ";      $ProcessorScore[475] = "4941"
    $ProcessorName[476] = "i7-4700HQ ";      $ProcessorScore[476] = "5458"
    $ProcessorName[477] = "i7-4700MQ ";      $ProcessorScore[477] = "5286"
    $ProcessorName[478] = "i7-4702HQ ";      $ProcessorScore[478] = "5382"
    $ProcessorName[479] = "i7-4702MQ ";      $ProcessorScore[479] = "5222"
    $ProcessorName[480] = "i7-4710HQ ";      $ProcessorScore[480] = "5470"
    $ProcessorName[481] = "i7-4710MQ ";      $ProcessorScore[481] = "5851"
    $ProcessorName[482] = "i7-4712HQ ";      $ProcessorScore[482] = "4618"
    $ProcessorName[483] = "i7-4712MQ ";      $ProcessorScore[483] = "5209"
    $ProcessorName[484] = "i7-4720HQ ";      $ProcessorScore[484] = "5634"
    $ProcessorName[485] = "i7-4722HQ ";      $ProcessorScore[485] = "5620"
    $ProcessorName[486] = "i7-4750HQ ";      $ProcessorScore[486] = "5348"
    $ProcessorName[487] = "i7-4760HQ ";      $ProcessorScore[487] = "6300"
    $ProcessorName[488] = "i7-4765T ";      $ProcessorScore[488] = "4867"
    $ProcessorName[489] = "i7-4770 ";      $ProcessorScore[489] = "7023"
    $ProcessorName[490] = "i7-4770HQ ";      $ProcessorScore[490] = "6158"
    $ProcessorName[491] = "i7-4770K ";      $ProcessorScore[491] = "7031"
    $ProcessorName[492] = "i7-4770R ";      $ProcessorScore[492] = "6666"
    $ProcessorName[493] = "i7-4770S ";      $ProcessorScore[493] = "6768"
    $ProcessorName[494] = "i7-4770T ";      $ProcessorScore[494] = "5957"
    $ProcessorName[495] = "i7-4770TE ";      $ProcessorScore[495] = "4257"
    $ProcessorName[496] = "i7-4771 ";      $ProcessorScore[496] = "6985"
    $ProcessorName[497] = "i7-4785T ";      $ProcessorScore[497] = "5291"
    $ProcessorName[498] = "i7-4790 ";      $ProcessorScore[498] = "7211"
    $ProcessorName[499] = "i7-4790K ";      $ProcessorScore[499] = "8052"
    $ProcessorName[500] = "i9-10880H ";      $ProcessorScore[500] = "15137"
    $ProcessorName[501] = "i7-4790S ";      $ProcessorScore[501] = "6971"
    $ProcessorName[502] = "i7-4790T ";      $ProcessorScore[502] = "6508"
    $ProcessorName[503] = "i7-4800MQ ";      $ProcessorScore[503] = "5937"
    $ProcessorName[504] = "i7-4810MQ ";      $ProcessorScore[504] = "6152"
    $ProcessorName[505] = "i7-4820K ";      $ProcessorScore[505] = "6531"
    $ProcessorName[506] = "i7-4850HQ ";      $ProcessorScore[506] = "6198"
    $ProcessorName[507] = "i7-4860EQ ";      $ProcessorScore[507] = "5280"
    $ProcessorName[508] = "i7-4860HQ ";      $ProcessorScore[508] = "6485"
    $ProcessorName[509] = "i7-4870HQ ";      $ProcessorScore[509] = "6359"
    $ProcessorName[510] = "i7-4900MQ ";      $ProcessorScore[510] = "6080"
    $ProcessorName[511] = "i7-4910MQ ";      $ProcessorScore[511] = "6185"
    $ProcessorName[512] = "i7-4930K ";      $ProcessorScore[512] = "9151"
    $ProcessorName[513] = "i7-4930MX ";      $ProcessorScore[513] = "6765"
    $ProcessorName[514] = "i7-4940MX ";      $ProcessorScore[514] = "6943"
    $ProcessorName[515] = "i7-4960HQ ";      $ProcessorScore[515] = "6638"
    $ProcessorName[516] = "i7-4960X ";      $ProcessorScore[516] = "9740"
    $ProcessorName[517] = "i7-4980HQ ";      $ProcessorScore[517] = "6735"
    $ProcessorName[518] = "i7-5500U ";      $ProcessorScore[518] = "2731"
    $ProcessorName[519] = "i7-5550U ";      $ProcessorScore[519] = "2908"
    $ProcessorName[520] = "i7-5557U ";      $ProcessorScore[520] = "3558"
    $ProcessorName[521] = "i7-5600U ";      $ProcessorScore[521] = "3065"
    $ProcessorName[522] = "i7-5650U ";      $ProcessorScore[522] = "3110"
    $ProcessorName[523] = "i7-5675C ";      $ProcessorScore[523] = "6089"
    $ProcessorName[524] = "i7-5700EQ ";      $ProcessorScore[524] = "5905"
    $ProcessorName[525] = "i7-5700HQ ";      $ProcessorScore[525] = "5951"
    $ProcessorName[526] = "i7-5775C ";      $ProcessorScore[526] = "7813"
    $ProcessorName[527] = "i7-5775R ";      $ProcessorScore[527] = "7819"
    $ProcessorName[528] = "i7-5820K ";      $ProcessorScore[528] = "9759"
    $ProcessorName[529] = "i7-5850EQ ";      $ProcessorScore[529] = "7036"
    $ProcessorName[530] = "i7-5850HQ ";      $ProcessorScore[530] = "6866"
    $ProcessorName[531] = "i7-5930K ";      $ProcessorScore[531] = "10230"
    $ProcessorName[532] = "i7-5950HQ ";      $ProcessorScore[532] = "7728"
    $ProcessorName[533] = "i7-5960X ";      $ProcessorScore[533] = "12692"
    $ProcessorName[534] = "i7-610E ";      $ProcessorScore[534] = "1818"
    $ProcessorName[535] = "i7-620LM ";      $ProcessorScore[535] = "1367"
    $ProcessorName[536] = "i7-620M ";      $ProcessorScore[536] = "1950"
    $ProcessorName[537] = "i7-620UM ";      $ProcessorScore[537] = "964"
    $ProcessorName[538] = "i7-640LM ";      $ProcessorScore[539] = "1623"
    $ProcessorName[539] = "i7-640M ";      $ProcessorScore[539] = "2050"
    $ProcessorName[540] = "i7-640UM ";      $ProcessorScore[540] = "1026"
    $ProcessorName[541] = "i7-6498DU ";      $ProcessorScore[541] = "3293"
    $ProcessorName[542] = "i7-6500U ";      $ProcessorScore[542] = "3279"
    $ProcessorName[543] = "i7-6560U ";      $ProcessorScore[543] = "3322"
    $ProcessorName[544] = "i7-6567U ";      $ProcessorScore[544] = "3825"
    $ProcessorName[545] = "i7-6600U ";      $ProcessorScore[545] = "3563"
    $ProcessorName[546] = "i7-660UM ";      $ProcessorScore[546] = "1284"
    $ProcessorName[547] = "i7-6650U ";      $ProcessorScore[547] = "3544"
    $ProcessorName[548] = "i7-6700 ";      $ProcessorScore[548] = "8036"
    $ProcessorName[549] = "i7-6700HQ ";      $ProcessorScore[549] = "6482"
    $ProcessorName[550] = "i7-6700K ";      $ProcessorScore[550] = "8954"
    $ProcessorName[551] = "i7-6700T ";      $ProcessorScore[551] = "7247"
    $ProcessorName[552] = "i7-6700TE ";      $ProcessorScore[552] = "6600"
    $ProcessorName[553] = "i7-6770HQ ";      $ProcessorScore[553] = "7338"
    $ProcessorName[554] = "i7-6800K ";      $ProcessorScore[554] = "10543"
    $ProcessorName[555] = "i7-680UM ";      $ProcessorScore[555] = "1196"
    $ProcessorName[556] = "i7-6820EQ ";      $ProcessorScore[556] = "6746"
    $ProcessorName[557] = "i7-6820HK ";      $ProcessorScore[557] = "7067"
    $ProcessorName[558] = "i7-6820HQ ";      $ProcessorScore[558] = "6892"
    $ProcessorName[559] = "i7-6822EQ ";      $ProcessorScore[559] = "5241"
    $ProcessorName[560] = "i7-6850K ";      $ProcessorScore[560] = "11266"
    $ProcessorName[561] = "i7-6900K ";      $ProcessorScore[561] = "13402"
    $ProcessorName[562] = "i7-6920HQ ";      $ProcessorScore[562] = "7307"
    $ProcessorName[563] = "i7-6950X ";      $ProcessorScore[563] = "17363"
    $ProcessorName[564] = "i7-720QM ";      $ProcessorScore[564] = "1686"
    $ProcessorName[565] = "i7-740QM ";      $ProcessorScore[565] = "1715"
    $ProcessorName[566] = "i7-7500U ";      $ProcessorScore[566] = "3673"
    $ProcessorName[567] = "i7-7560U ";      $ProcessorScore[567] = "3920"
    $ProcessorName[568] = "i7-7567U ";      $ProcessorScore[568] = "4188"
    $ProcessorName[569] = "i7-7600U ";      $ProcessorScore[569] = "3630"
    $ProcessorName[570] = "i7-7660U ";      $ProcessorScore[570] = "4163"
    $ProcessorName[571] = "i7-7700 ";      $ProcessorScore[571] = "8661"
    $ProcessorName[572] = "i7-7700HQ ";      $ProcessorScore[572] = "6960"
    $ProcessorName[573] = "i7-7700K ";      $ProcessorScore[573] = "9729"
    $ProcessorName[574] = "i7-7700T ";      $ProcessorScore[574] = "7814"
    $ProcessorName[575] = "i7-7740X ";      $ProcessorScore[575] = "9940"
    $ProcessorName[576] = "i7-7800X ";      $ProcessorScore[576] = "12702"
    $ProcessorName[577] = "i7-7820EQ ";      $ProcessorScore[577] = "7059"
    $ProcessorName[578] = "i7-7820HK ";      $ProcessorScore[578] = "7884"
    $ProcessorName[579] = "i7-7820HQ ";      $ProcessorScore[579] = "7179"
    $ProcessorName[580] = "i7-7820X ";      $ProcessorScore[580] = "17489"
    $ProcessorName[581] = "i7-7900X ";      $ProcessorScore[581] = "19358"
    $ProcessorName[582] = "i7-7920HQ ";      $ProcessorScore[582] = "7694"
    $ProcessorName[583] = "i7-7Y75 ";      $ProcessorScore[583] = "2715"
    $ProcessorName[584] = "i7-8086K ";      $ProcessorScore[584] = "14717"
    $ProcessorName[585] = "i7-820QM ";      $ProcessorScore[585] = "1921"
    $ProcessorName[586] = "i7-840QM ";      $ProcessorScore[586] = "1894"
    $ProcessorName[587] = "i7-8500Y ";      $ProcessorScore[587] = "3189"
    $ProcessorName[588] = "i7-8550U ";      $ProcessorScore[588] = "6002"
    $ProcessorName[589] = "i7-8557U ";      $ProcessorScore[589] = "7820"
    $ProcessorName[590] = "i7-8559U ";      $ProcessorScore[590] = "8892"
    $ProcessorName[591] = "i7-8565U ";      $ProcessorScore[591] = "6489"
    $ProcessorName[592] = "i7-8565UC ";      $ProcessorScore[592] = "6187"
    $ProcessorName[593] = "i7-8569U ";      $ProcessorScore[593] = "9251"
    $ProcessorName[594] = "i7-860 ";      $ProcessorScore[594] = "2887"
    $ProcessorName[595] = "i7-860S ";      $ProcessorScore[595] = "2725"
    $ProcessorName[596] = "i7-8650U ";      $ProcessorScore[596] = "6584"
    $ProcessorName[597] = "i7-8665U ";      $ProcessorScore[597] = "6602"
    $ProcessorName[598] = "i7-8665UE ";      $ProcessorScore[598] = "6587"
    $ProcessorName[599] = "i7-870 ";      $ProcessorScore[599] = "3036"
    $ProcessorName[600] = "i7-8700 ";      $ProcessorScore[600] = "13115"
    $ProcessorName[601] = "i7-8700B ";      $ProcessorScore[601] = "12286"
    $ProcessorName[602] = "i7-8700K ";      $ProcessorScore[602] = "13887"
    $ProcessorName[603] = "i7-8700T ";      $ProcessorScore[603] = "10779"
    $ProcessorName[604] = "i7-8705G ";      $ProcessorScore[604] = "7974"
    $ProcessorName[605] = "i7-8706G ";      $ProcessorScore[605] = "8136"
    $ProcessorName[606] = "i7-8709G ";      $ProcessorScore[606] = "7921"
    $ProcessorName[607] = "i7-870S ";      $ProcessorScore[607] = "2786"
    $ProcessorName[608] = "i7-8750H ";      $ProcessorScore[608] = "10203"
    $ProcessorName[609] = "i7-875K ";      $ProcessorScore[609] = "3028"
    $ProcessorName[610] = "i7-880 ";      $ProcessorScore[610] = "3205"
    $ProcessorName[611] = "i7-8809G ";      $ProcessorScore[611] = "8774"
    $ProcessorName[612] = "i7-8850H ";      $ProcessorScore[612] = "10439"
    $ProcessorName[613] = "i7-920 ";      $ProcessorScore[613] = "2734"
    $ProcessorName[614] = "i7-920XM ";      $ProcessorScore[614] = "2178"
    $ProcessorName[615] = "i7-930 ";      $ProcessorScore[615] = "2921"
    $ProcessorName[616] = "i7-940 ";      $ProcessorScore[616] = "3081"
    $ProcessorName[617] = "i7-940XM ";      $ProcessorScore[617] = "2308"
    $ProcessorName[618] = "i7-950 ";      $ProcessorScore[618] = "3074"
    $ProcessorName[619] = "i7-960 ";      $ProcessorScore[619] = "3219"
    $ProcessorName[620] = "i7-965 ";      $ProcessorScore[620] = "3269"
    $ProcessorName[621] = "i7-970 ";      $ProcessorScore[621] = "6719"
    $ProcessorName[622] = "i7-9700 ";      $ProcessorScore[622] = "13613"
    $ProcessorName[623] = "i7-9700F ";      $ProcessorScore[623] = "13757"
    $ProcessorName[624] = "i7-9700K ";      $ProcessorScore[624] = "14603"
    $ProcessorName[625] = "i7-9700KF ";      $ProcessorScore[625] = "14711"
    $ProcessorName[626] = "i7-9700T ";      $ProcessorScore[626] = "10885"
    $ProcessorName[627] = "i7-9700TE ";      $ProcessorScore[627] = "10680"
    $ProcessorName[628] = "i7-975 ";      $ProcessorScore[628] = "3331"
    $ProcessorName[629] = "i7-9750H ";      $ProcessorScore[629] = "11385"
    $ProcessorName[630] = "i7-9750HF ";      $ProcessorScore[630] = "11803"
    $ProcessorName[631] = "i7-980 ";      $ProcessorScore[631] = "6922"
    $ProcessorName[632] = "i7-9800X ";      $ProcessorScore[632] = "18337"
    $ProcessorName[633] = "i7-980X ";      $ProcessorScore[633] = "6757"
    $ProcessorName[634] = "i7-985 ";      $ProcessorScore[634] = "3928"
    $ProcessorName[635] = "i7-9850H ";      $ProcessorScore[635] = "11643"
    $ProcessorName[636] = "i7-9850HL ";      $ProcessorScore[636] = "9112"
    $ProcessorName[637] = "i7-990X ";      $ProcessorScore[637] = "7298"
    $ProcessorName[638] = "i7-995X ";      $ProcessorScore[638] = "7079"
    $ProcessorName[639] = "i9-9990XE ";      $ProcessorScore[639] = "31941"
    $ProcessorName[640] = "i9-9980XE ";      $ProcessorScore[640] = "31556"
    $ProcessorName[641] = "i9-9980HK ";      $ProcessorScore[641] = "15298"
    $ProcessorName[642] = "i9-9960X ";      $ProcessorScore[642] = "30663"
    $ProcessorName[643] = "i9-9940X ";      $ProcessorScore[643] = "28242"
    $ProcessorName[644] = "i9-9920X ";      $ProcessorScore[644] = "25389"
    $ProcessorName[645] = "i9-9900X ";      $ProcessorScore[645] = "21679"
    $ProcessorName[646] = "i9-9900T ";      $ProcessorScore[646] = "13609"
    $ProcessorName[647] = "i9-9900KS ";      $ProcessorScore[647] = "19470"
    $ProcessorName[648] = "i9-9900KF ";      $ProcessorScore[648] = "18801"
    $ProcessorName[649] = "i9-9900K ";      $ProcessorScore[649] = "18876"
    $ProcessorName[650] = "i9-9900 ";      $ProcessorScore[650] = "17181"
    $ProcessorName[651] = "i9-9880H ";      $ProcessorScore[651] = "14081"
    $ProcessorName[652] = "i9-9820X ";      $ProcessorScore[652] = "20626"
    $ProcessorName[653] = "i9-8950HK ";      $ProcessorScore[653] = "10755"
    $ProcessorName[654] = "i9-7980XE ";      $ProcessorScore[654] = "29541"
    $ProcessorName[655] = "i9-7960X ";      $ProcessorScore[655] = "27264"
    $ProcessorName[656] = "i9-7940X ";      $ProcessorScore[656] = "26864"
    $ProcessorName[657] = "i9-7920X ";      $ProcessorScore[657] = "23338"
    $ProcessorName[658] = "i9-7900X ";      $ProcessorScore[658] = "21428"
    $ProcessorName[659] = "i9-10980XE ";      $ProcessorScore[659] = "34264"
    $ProcessorName[660] = "i9-10980HK ";      $ProcessorScore[660] = "17308"
    $ProcessorName[661] = "i9-10940X ";      $ProcessorScore[661] = "29673"
    $ProcessorName[662] = "i9-10920X ";      $ProcessorScore[662] = "26257"
    $ProcessorName[663] = "i9-10910 ";      $ProcessorScore[663] = "22090"
    $ProcessorName[664] = "i9-10900X ";      $ProcessorScore[664] = "22960"
    $ProcessorName[665] = "i9-10900T ";      $ProcessorScore[665] = "16991"
    $ProcessorName[666] = "i9-10900KF ";      $ProcessorScore[666] = "23539"
    $ProcessorName[667] = "i9-10900K ";      $ProcessorScore[667] = "24181"
    $ProcessorName[668] = "i9-10900F ";      $ProcessorScore[668] = "21228"
    $ProcessorName[669] = "i9-10900 ";      $ProcessorScore[669] = "21289"
    $ProcessorName[670] = "i9-10885H ";      $ProcessorScore[670] = "16381"
    $ProcessorName[671] = "i9-10880H ";      $ProcessorScore[671] = "15137"
    $ProcessorName[672] = "E3400 ";      $ProcessorScore[672] = "841"
    $ProcessorName[673] = "E5504 ";      $ProcessorScore[673] = "1529"
    $ProcessorName[674] = "E7500 ";      $ProcessorScore[674] = "1099"
    $ProcessorName[675] = "E8400 ";      $ProcessorScore[675] = "1161"
    $ProcessorName[676] = "E5-2609 v2 ";      $ProcessorScore[676] = "3851"
    $ProcessorName[677] = "E5-2620 v3 ";      $ProcessorScore[677] = "7981"
    $ProcessorName[678] = "E5-2620 v4 ";      $ProcessorScore[678] = "8699"
    $ProcessorName[679] = "E5400 ";      $ProcessorScore[679] = "880"
    $ProcessorName[680] = "E2180 ";      $ProcessorScore[680] = "662"
    $ProcessorName[681] = "J3710 ";      $ProcessorScore[681] = "1409"
    $ProcessorName[682] = "G3260 ";      $ProcessorScore[682] = "2053"
    $ProcessorName[683] = "G3260T ";      $ProcessorScore[683] = "1993"
    $ProcessorName[684] = "A8-6500 ";      $ProcessorScore[684] = "2738"
    $ProcessorName[685] = "E7200 ";      $ProcessorScore[685] = "963"
    $ProcessorName[686] = "7300B ";      $ProcessorScore[686] = "1448"
    $ProcessorName[687] = "CPU 6300 ";      $ProcessorScore[687] = "521"
    $ProcessorName[688] = "CPU 6400 ";      $ProcessorScore[688] = "786"
    $ProcessorName[689] = "E6550 ";      $ProcessorScore[689] = "883"
    $ProcessorName[690] = "E7600 ";      $ProcessorScore[690] = "1138"
    $ProcessorName[691] = "E8500 ";      $ProcessorScore[691] = "1243"
    $ProcessorName[692] = "1220 v3 ";      $ProcessorScore[692] = "5198"
    $ProcessorName[693] = "1226 v3 ";      $ProcessorScore[693] = "5354"
    $ProcessorName[694] = "1245 v3 ";      $ProcessorScore[694] = "7024"
    $ProcessorName[695] = "E5-1620 v3 ";      $ProcessorScore[695] = "7020"
    $ProcessorName[696] = "E5-1620 v4 ";      $ProcessorScore[696] = "7322"
    $ProcessorName[697] = "E5-2609 v4 ";      $ProcessorScore[697] = "5974"
    $ProcessorName[698] = "E5300 ";      $ProcessorScore[698] = "976"
    $ProcessorName[699] = "E5700 ";      $ProcessorScore[699] = "1057"
    $ProcessorName[700] = "Silver 4110 ";      $ProcessorScore[700] = "10453"
    $ProcessorName[701] = "E5-2630 v3 ";      $ProcessorScore[701] = "9694"
    $ProcessorName[702] = "N270 ";      $ProcessorScore[702] = "175"
    $ProcessorName[703] = "x5-Z8350 ";      $ProcessorScore[703] = "922"
    $ProcessorName[704] = "Z3735F ";      $ProcessorScore[704] = "529"
    $ProcessorName[705] = "7 2700X ";      $ProcessorScore[705] = "17576"
    $ProcessorName[706] = "X4 635 ";      $ProcessorScore[706] = "2196"
    $ProcessorName[707] = "E5-1650 v2 ";      $ProcessorScore[707] = "8977"
    $ProcessorName[708] = "CPU 960 ";      $ProcessorScore[708] = "3219"
    $ProcessorName[709] = "CPU 650 ";      $ProcessorScore[709] = "2200"
    $ProcessorName[710] = "D CPU 3.40GHz";      $ProcessorScore[710] = "634"
    $ProcessorName[711] = "E5-1620 v4 ";      $ProcessorScore[711] = "7322"
    $ProcessorName[712] = "E5-2620 0 ";      $ProcessorScore[712] = "5179"
    $ProcessorName[713] = "E5-1650 0 ";      $ProcessorScore[713] = "8176"
    $ProcessorName[714] = "E3-1245 v6 ";      $ProcessorScore[714] = "8455"
    $ProcessorName[715] = "J2900 ";      $ProcessorScore[715] = "1216"
    $ProcessorName[716] = "Ryzen 5 Microsoft Surface ";      $ProcessorScore[716] = "8065"
    $ProcessorName[717] = "A8-6410 ";      $ProcessorScore[717] = "1766"
    $ProcessorName[718] = "A8-5500 ";      $ProcessorScore[718] = "2557"
    $ProcessorName[719] = "A6-7310 ";      $ProcessorScore[719] = "1699"
    $ProcessorName[720] = "A6-5200 ";      $ProcessorScore[720] = "1632"
    $ProcessorName[721] = "A10-7800 ";      $ProcessorScore[721] = "3118"
    $ProcessorName[722] = "E5-2407 0 ";      $ProcessorScore[722] = "2661"
    $ProcessorName[723] = "A10-6700 APU";      $ProcessorScore[723] = "3130"
    $ProcessorName[724] = "E5620 @";      $ProcessorScore[724] = "3709"
    $ProcessorName[725] = "E5-2420 0 @";      $ProcessorScore[725] = "5165"
    $ProcessorName[726] = "Silver 4216 CPU @";      $ProcessorScore[726] = "18561"
    $ProcessorName[727] = "E5-2430 0 @";      $ProcessorScore[727] = "5867"
    $ProcessorName[728] = "X5667 @";      $ProcessorScore[728] = "4534"
    $ProcessorName[729] = "X5650 @";      $ProcessorScore[729] = "5796"
    $ProcessorName[730] = "A4-3400 APU";      $ProcessorScore[730] = "1049"
    $ProcessorName[731] = "E3-1230 v5 @";      $ProcessorScore[731] = "7746"
    $ProcessorName[732] = "EPYC 7251 ";      $ProcessorScore[732] = "15542"
    $ProcessorName[733] = "E5-2420 v2 @";      $ProcessorScore[733] = "6490"
    $ProcessorName[734] = "i3 CPU 540 @";      $ProcessorScore[734] = "1503"
    $ProcessorName[735] = "1214 HE ";      $ProcessorScore[735] = "806"
    $ProcessorName[736] = "Ryzen 5 2600X ";      $ProcessorScore[736] = "14080"
    $ProcessorName[737] = "i5 CPU M 560 @";      $ProcessorScore[737] = "1848"
    $ProcessorName[738] = "CPU E3-1220 v5 @";      $ProcessorScore[738] = "5687"
    $ProcessorName[739] = "A9-9400 ";      $ProcessorScore[739] = "1407"
    $ProcessorName[740] = "E5-2640 0 @";      $ProcessorScore[740] = "6314"
    $ProcessorName[741] = "E5-2690 v2 @";      $ProcessorScore[741] = "13116"
    $ProcessorName[742] = "A9-9425 ";      $ProcessorScore[742] = "1554"
    $ProcessorName[743] = "E-2234 CPU @";      $ProcessorScore[743] = "9555"
    $ProcessorName[744] = "CPU E5620 @";      $ProcessorScore[744] = "3709"
    $ProcessorName[745] = "E5-2690 v2 @";      $ProcessorScore[745] = "13116"
    $ProcessorName[746] = "E3-1271 v3 @";      $ProcessorScore[746] = "7308"
    $ProcessorName[747] = "E-2234 CPU @";      $ProcessorScore[747] = "9555"
    $ProcessorName[748] = "Silver 4215 CPU @";      $ProcessorScore[748] = "14439"
    $ProcessorName[749] = "E5-2673 v4 @";      $ProcessorScore[749] = "17533"
    $ProcessorName[750] = "Gold 5215 CPU @";      $ProcessorScore[750] = "16058"
    $ProcessorName[751] = "AMD FX(tm)-6100 ";      $ProcessorScore[751] = "3642"
    $ProcessorName[752] = "E-2278G CPU @";      $ProcessorScore[752] = "17609"
    $ProcessorName[753] = "CPU 4205U @";      $ProcessorScore[753] = "1300"
    $ProcessorName[754] = "AMD A4-9125 ";      $ProcessorScore[754] = "1216"
    $ProcessorName[755] = "W-2104 CPU @";      $ProcessorScore[755] = "6362"
    $ProcessorName[756] = "9150e ";      $ProcessorScore[756] = "1267"
    $ProcessorName[757] = "CPU E5-2667 v4 @";      $ProcessorScore[757] = "14148"
    $ProcessorName[758] = "i7 CPU 930 @";      $ProcessorScore[758] = "2871"
    $ProcessorName[759] = "CPU E5-2403 v2 @";      $ProcessorScore[759] = "2873"
    $ProcessorName[760] = "W-2104 CPU @";      $ProcessorScore[760] = "6362"
    $ProcessorName[761] = "CPU X5650 @";      $ProcessorScore[761] = "5796"
    $ProcessorName[762] = "E5-1620 0 @";      $ProcessorScore[762] = "5862"
    $ProcessorName[763] = "E5620 @";      $ProcessorScore[763] = "3709"
    $ProcessorName[764] = "E5-2673 v3 @";      $ProcessorScore[764] = "13738"
    $ProcessorName[765] = "N3150 @";      $ProcessorScore[765] = "1189"
    $ProcessorName[766] = "P8700 @";      $ProcessorScore[766] = "945"
    $ProcessorName[767] = "E5-2630L 0 @";      $ProcessorScore[767] = "5285"
    $ProcessorName[768] = "E5-2690 v2 @";      $ProcessorScore[768] = "13116"
    $ProcessorName[769] = "i5 CPU M 560 @";      $ProcessorScore[769] = "1626"
    $ProcessorName[770] = "E3-1230 V2 @";      $ProcessorScore[770] = "6193"
    $ProcessorName[771] = "E-2134 CPU @";      $ProcessorScore[771] = "8253"
    $ProcessorName[772] = "E3-1270 v5 @";      $ProcessorScore[772] = "8456"
    $ProcessorName[773] = "E3-1220L V2 @";      $ProcessorScore[773] = "2687"
    $ProcessorName[774] = "Platinum 8171M CPU @";      $ProcessorScore[774] = "27000"
    $ProcessorName[775] = "2 Duo CPU E8600 @";      $ProcessorScore[775] = "1338"
    $ProcessorName[776] = "2 Duo CPU E8200 @";      $ProcessorScore[776] = "983"
    $ProcessorName[777] = "Ryzen 3 2200U";      $ProcessorScore[777] = "3692"
    $ProcessorName[778] = "i7-9750H CPU @ ";      $ProcessorScore[778] = "11337"
    $ProcessorName[779] = "E5-2650 v2 @";      $ProcessorScore[779] = "9986"
    $ProcessorName[780] = "E-2136 CPU @";      $ProcessorScore[780] = "13506"
    $ProcessorName[781] = "FX-9800P ";      $ProcessorScore[781] = "2125"
    $ProcessorName[782] = "Ryzen 5 4500U ";      $ProcessorScore[782] = "11273"
    $ProcessorName[783] = "i5-11300H @";      $ProcessorScore[783] = "11056"
    $ProcessorName[784] = "i5-11400 @";      $ProcessorScore[784] = "17066"
    $ProcessorName[785] = "i5-11400H @";      $ProcessorScore[785] = "15986"
    $ProcessorName[786] = "i5-11500 @";      $ProcessorScore[786] = "17629"
    $ProcessorName[787] = "i5-11500H @";      $ProcessorScore[787] = "16133"
    $ProcessorName[788] = "i5-11600 @";      $ProcessorScore[788] = "18236"
    $ProcessorName[789] = "i7-11370H @";      $ProcessorScore[789] = "11937"
    $ProcessorName[790] = "i7-11390H @";      $ProcessorScore[790] = "10545"
    $ProcessorName[791] = "i7-11700 @";      $ProcessorScore[791] = "20114"
    $ProcessorName[792] = "i7-11800H @";      $ProcessorScore[792] = "21154"
    $ProcessorName[793] = "i7-11850H @";      $ProcessorScore[793] = "21117"
    $ProcessorName[794] = "i9-11950H @";      $ProcessorScore[794] = "22414"
    $ProcessorName[795] = "i7-12800HX";      $ProcessorScore[795] = "35483"
    $ProcessorName[796] = "i7-12800H";      $ProcessorScore[796] = "24247"
    $ProcessorName[797] = "A10-9620P";      $ProcessorScore[797] = "2541"
    $ProcessorName[798] = "E1-2500 APU";      $ProcessorScore[798] = "595"
    $ProcessorName[799] = "A10-8770E";      $ProcessorScore[799] = "3075"
    $ProcessorName[800] = "A10-8770";      $ProcessorScore[800] = "3465"
    $ProcessorName[801] = "3 3200U";      $ProcessorScore[801] = "3868"
    $ProcessorName[802] = "5 2500U";      $ProcessorScore[802] = "6533"
    $ProcessorName[803] = "5 3500U";      $ProcessorScore[803] = "7069"
    $ProcessorName[804] = "5 5600X";      $ProcessorScore[804] = "21975"
    $ProcessorName[805] = "O 3400GE";      $ProcessorScore[805] = "8270"
    $ProcessorName[806] = "V1605B";      $ProcessorScore[806] = "6866"
    $ProcessorName[807] = "x7-Z8700";      $ProcessorScore[807] = "1323"
    $ProcessorName[808] = "i5-10505 CPU @";      $ProcessorScore[808] = "12336"
    $ProcessorName[809] = "E8200 @";      $ProcessorScore[809] = "1075"
    $ProcessorName[810] = "Q6600 @";      $ProcessorScore[810] = "1780"
    $ProcessorName[811] = "N3700 @";      $ProcessorScore[811] = "1247"
    $ProcessorName[812] = "G3250 @";      $ProcessorScore[812] = "1945"
    $ProcessorName[813] = "J5005 CPU @";      $ProcessorScore[813] = "3043"
    $ProcessorName[814] = "5110 @";      $ProcessorScore[814] = "600"
    $ProcessorName[815] = "E5502 @";      $ProcessorScore[815] = "837"
    $ProcessorName[816] = "L5520 @";      $ProcessorScore[816] = "2238"
    $ProcessorName[817] = "X5570 @";      $ProcessorScore[817] = "3270"
    $ProcessorName[818] = "X5667 @";      $ProcessorScore[818] = "4551"
    $ProcessorName[819] = "E3-1245 v5 @";      $ProcessorScore[819] = "7933"
    $ProcessorName[820] = "E5-2630 v4 @";      $ProcessorScore[820] = "11622"
    $ProcessorName[821] = "E5-2640 v3 @";      $ProcessorScore[821] = "11327"
    $ProcessorName[822] = "E5-2650 v3 @";      $ProcessorScore[822] = "11781"
    $ProcessorName[823] = "E5-2650 v4 @";      $ProcessorScore[823] = "13839"
    $ProcessorName[824] = "E5-2667 v3 @";      $ProcessorScore[824] = "12378"
    $ProcessorName[825] = "E5-2680 v2 @";      $ProcessorScore[825] = "12671"
    $ProcessorName[826] = "E5-2690 v2 @";      $ProcessorScore[826] = "13535"
    $ProcessorName[827] = "E-2144G";      $ProcessorScore[827] = "9322"
    $ProcessorName[828] = "E-2246G";      $ProcessorScore[828] = "14050"
    $ProcessorName[829] = "Silver 4208";      $ProcessorScore[829] = "11157"
    $ProcessorName[830] = "W-10855M";      $ProcessorScore[830] = "12902"
    $ProcessorName[831] = "W-2223";      $ProcessorScore[831] = "8706"
    $ProcessorName[832] = "W-2225";      $ProcessorScore[832] = "10794"
    $ProcessorName[833] = "i5-9500T CPU @";      $ProcessorScore[833] = "8161"
    $ProcessorName[834] = "E5-2690 v2 @";      $ProcessorScore[834] = "13454"
    $ProcessorName[835] = "Ryzen 7 Microsoft Surface (R)";      $ProcessorScore[835] = "17459"
    $ProcessorName[836] = "Core(TM) i7-12800H ";      $ProcessorScore[836] = "24919"
    $ProcessorName[837] = "i3-10105T CPU @";      $ProcessorScore[837] = "8012"
    $ProcessorName[838] = "i5-1240P";      $ProcessorScore[838] = "17351"
    $ProcessorName[839] = "i7-12700H ";      $ProcessorScore[839] = "26462"
    $ProcessorName[840] = "i7-1260P";      $ProcessorScore[840] = "17215"
    $ProcessorName[841] = "Ryzen 7 5825U";      $ProcessorScore[841] = "18426"
    $ProcessorName[842] = "i5-1145G7 @";      $ProcessorScore[842] = "9959"
    $ProcessorName[843] = "i5-1135G7 @";      $ProcessorScore[843] = "9902"
    $ProcessorName[844] = "i5-12500 ";      $ProcessorScore[844] = "19977"
    $ProcessorName[845] = "i5-1245U ";      $ProcessorScore[845] = "13508"
    $ProcessorName[846] = "i9-12900K ";      $ProcessorScore[846] = "41418"
    $ProcessorName[847] = "W-2102 CPU @";      $ProcessorScore[847] = "5081"
    $ProcessorName[848] = "i7-11700K @";      $ProcessorScore[848] = "24663"
    $ProcessorName[849] = "W-2125 CPU @";      $ProcessorScore[849] = "10030"
    $ProcessorName[850] = "Ryzen 5 5600G";      $ProcessorScore[850] = "19912"
    $ProcessorName[851] = "i5-12500T ";      $ProcessorScore[851] = "16738"
    $ProcessorName[852] = "Ryzen 9 7950X";      $ProcessorScore[852] = "63223"
    $ProcessorName[854] = "i7-12700 ";      $ProcessorScore[853] = "30911"
    $ProcessorName[854] = "i7-1255U ";      $ProcessorScore[854] = "13790"
    $ProcessorName[855] = "i7-7820HQ CPU ";      $ProcessorScore[855] = "7184"
    $ProcessorName[856] = "i7-1260P ";      $ProcessorScore[856] = "17212"
    $ProcessorName[857] = "i7-1255U ";      $ProcessorScore[857] = "13794"
    $ProcessorName[858] = "Ryzen 5 PRO 5675U ";      $ProcessorScore[858] = "14448"
    $ProcessorName[859] = "i5-1235U ";      $ProcessorScore[859] = "13594"
    $ProcessorName[860] = "i3-10105T CPU ";      $ProcessorScore[860] = "8012"



    $ProcessorName[861] = "Done";      $ProcessorScore[861] = "Done"
    $TotalNumber = 861



    $Count = 0


    $Score = "Unknown"
    WHILE ( $ProcessorName[$Count] -ne "Done" )    {
        IF ( $WorkstationProcessorName -cmatch $ProcessorName[$Count] ) { 
            $Score = $ProcessorScore[$Count]
            break
        }
        ELSE { $Count++ }
    } 

    return $Score
}
Function Get-PCAge {

    <#
    .SYNOPSIS
        Extimates the computers approximate age based on CPU model release date.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            Currently only works for Intel workstation processors, doesn't work for AMD or Xeon processors.
            Processors maybe be 3+ months old before companies like Dell and HP start selling computers with those model CPUs.
            Not unusual for a brand new current gen computer to report 6-12 months old.
             
            It is possible to purchase brand new computers with old processor models, so a brand new computer can report as 3+ years old.
            I usually use the comparison of buying a car to help the client understand when they buy an old processor model.
            If you buy a 2020 model car in 2023, it is still 3 years old even though you just bought it.
 
        TIPS
            Combine this with the Get-CPUScore function to get a good idea for which computers a client might need to replace soon.
 
    .EXAMPLE
        Get-PCAge
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>

    
    $CPUName = Get-ProcessorName
    $Now = Get-Date
    [string]$CPUDate = "Unknown"
    IF($CPUName -like "*i3-14*" -or $CPUName -like "*i5-14*" -or $CPUName -like "*i7-14*" -or $CPUName -like "*i9-14*") { [DateTime]$CPUDate = "NOV 2023" }
    IF($CPUName -like "*i3-13*" -or $CPUName -like "*i5-13*" -or $CPUName -like "*i7-13*" -or $CPUName -like "*i9-12*") { [DateTime]$CPUDate = "NOV 2022" }
    IF($CPUName -like "*i3-12*" -or $CPUName -like "*i5-12*" -or $CPUName -like "*i7-12*" -or $CPUName -like "*i9-13*") { [DateTime]$CPUDate = "NOV 2021" }
    IF($CPUName -like "*i3-11*" -or $CPUName -like "*i5-11*" -or $CPUName -like "*i7-11*" -or $CPUName -like "*i9-11*") { [DateTime]$CPUDate = "AUG 2020" }
    IF($CPUName -like "*i3-10*" -or $CPUName -like "*i5-10*" -or $CPUName -like "*i7-10*" -or $CPUName -like "*i9-10*") { [DateTime]$CPUDate = "NOV 2019" }
    IF($CPUName -like "*i3-9*" -or $CPUName -like "*i5-9*" -or $CPUName -like "*i7-9*" -or $CPUName -like "*i9-9*") { [DateTime]$CPUDate = "FEB 2019" }
    IF($CPUName -like "*i3-8*" -or $CPUName -like "*i5-8*" -or $CPUName -like "*i7-8*" -or $CPUName -like "*i9-8*") { [DateTime]$CPUDate = "DEC 2017" }
    IF($CPUName -like "*i3-7*" -or $CPUName -like "*i5-7*" -or $CPUName -like "*i7-7*" -or $CPUName -like "*i9-7*") { [DateTime]$CPUDate = "NOV 2016" }
    IF($CPUName -like "*i3-6*" -or $CPUName -like "*i5-6*" -or $CPUName -like "*i7-6*" -or $CPUName -like "*i9-6*") { [DateTime]$CPUDate = "NOV 2015" }
    IF($CPUName -like "*i3-5*" -or $CPUName -like "*i5-5*" -or $CPUName -like "*i7-5*" -or $CPUName -like "*i9-5*") { [DateTime]$CPUDate = "FEB 2015" }
    IF($CPUName -like "*i3-4*" -or $CPUName -like "*i5-4*" -or $CPUName -like "*i7-4*" -or $CPUName -like "*i9-4*") { [DateTime]$CPUDate = "MAY 2014" }
    IF($CPUName -like "*i3-3*" -or $CPUName -like "*i5-3*" -or $CPUName -like "*i7-3*" -or $CPUName -like "*i9-3*") { [DateTime]$CPUDate = "MAY 2013" }
    IF($CPUName -like "*i3-2*" -or $CPUName -like "*i5-2*" -or $CPUName -like "*i7-2*" -or $CPUName -like "*i9-2*") { [DateTime]$CPUDate = "NOV 2012" }

    IF ($CPUDate -eq "Unknown") { return "Unknown" }

    $AgeDifference = $Now - $CPUDate

        $OutString = $null
    [string]$OutString += [int]($AgeDifference.TotalDays / 365)
    IF([int]($AgeDifference.TotalDays / 365) -eq 1) {  [string]$OutString += " Year, " }
    ELSE { [string]$OutString += " Years, " }
    [string]$OutString += [int](($AgeDifference.TotalDays % 365) / 30.416)
    IF([int]($AgeDifference.TotalDays / 365) -eq 1) {  [string]$OutString += " Month " }
    ELSE { [string]$OutString += " Months " }
    [string]$OutString += "(+/- 3 Months)"

    Return $OutString
}
Function Get-DiskPerformance {

    $ExeFolder = "C:\Windows\System32\WindowsPowerShell\v1.0\Modules\IntegrisPowerShell"
   
    $RandomTest = & "$ExeFolder\diskspd.exe" -b4k -d10 -t1 -O32 -r -W2 -C2 -w0 -Z -c1G -Su "$ExeFolder\test.dat"
    $RandomTestResults = $RandomTest[-15] | convertfrom-csv -Delimiter "|" -Header Bytes,IO,Mib,IOPS,File | Select-Object IO,MIB,IOPs
    [int]$RandomMBs = $RandomTestResults.Mib
  
    IF ($RandomMBs -gt 200) {
        Write-Host " Random Read Results:"$RandomMBs.ToString().PadLeft(4,' ') "MB/s (Crazy Fast)"
    }
    ELSEIF ($RandomMBs -gt 100) {
        Write-Host " Random Read Results:"$RandomMBs.ToString().PadLeft(4,' ') "MB/s (Extremely Fast)"
    }
    ELSEIF ($RandomMBs -gt 60) {
        Write-Host " Random Read Results:"$RandomMBs.ToString().PadLeft(4,' ') "MB/s (Very Fast)"
    }
    ELSEIF ($RandomMBs -gt 30) {
        Write-Host " Random Read Results:"$RandomMBs.ToString().PadLeft(4,' ') "MB/s (Fast)"
    }
    ELSEIF ($RandomMBs -gt 15) {
        Write-Host " Random Read Results:"$RandomMBs.ToString().PadLeft(4,' ') "MB/s (Good)"
    }
    ELSEIF ($RandomMBs -gt 8) {
        Write-Host " Random Read Results:"$RandomMBs.ToString().PadLeft(4,' ') "MB/s (Acceptable)"
    }
    ELSEIF ($RandomMBs -gt 3) {
        Write-Host " Random Read Results:"$RandomMBs.ToString().PadLeft(4,' ') "MB/s (Slow)"
    }
    ELSEIF ($RandomMBs -gt 1) {
        Write-Host " Random Read Results:"$RandomMBs.ToString().PadLeft(4,' ') "MB/s (Very Slow)"
    }
    ELSE {
        Write-Host " Random Read Results:"$RandomMBs.ToString().PadLeft(4,' ') "MB/s (Extremely Slow)"
    }
    


    $Random4kWrite = & "$ExeFolder\diskspd.exe" -b4k -d10 -t1 -O32 -r -W2 -C2 -w100 -Z -c1G -Su "$ExeFolder\test.dat"
    $Random4kWriteResults = $Random4kWrite[-15] | convertfrom-csv -Delimiter "|" -Header Bytes,IO,Mib,IOPS,File | Select-Object IO,MIB,IOPs

    [int]$RandomWriteMBs = $Random4kWriteResults.Mib

    IF ($RandomWriteMBs -gt 200) {
        Write-Host " Random Write Results:"$RandomWriteMBs.ToString().PadLeft(4,' ') "MB/s (Crazy Fast)"
    }
    ELSEIF ($RandomWriteMBs -gt 100) {
        Write-Host " Random Write Results:"$RandomWriteMBs.ToString().PadLeft(4,' ') "MB/s (Extremely Fast)"
    }
    ELSEIF ($RandomWriteMBs -gt 60) {
        Write-Host " Random Write Results:"$RandomWriteMBs.ToString().PadLeft(4,' ') "MB/s (Very Fast)"
    }
    ELSEIF ($RandomWriteMBs -gt 30) {
        Write-Host " Random Write Results:"$RandomWriteMBs.ToString().PadLeft(4,' ') "MB/s (Fast)"
    }
    ELSEIF ($RandomWriteMBs -gt 15) {
        Write-Host " Random Write Results:"$RandomWriteMBs.ToString().PadLeft(4,' ') "MB/s (Good)"
    }
    ELSEIF ($RandomWriteMBs -gt 8) {
        Write-Host " Random Write Results:"$RandomWriteMBs.ToString().PadLeft(4,' ') "MB/s (Acceptable)"
    }
    ELSEIF ($RandomWriteMBs -gt 3) {
        Write-Host " Random Write Results:"$RandomWriteMBs.ToString().PadLeft(4,' ') "MB/s (Slow)"
    }
    ELSEIF ($RandomWriteMBs -gt 1) {
        Write-Host " Random Write Results:"$RandomWriteMBs.ToString().PadLeft(4,' ') "MB/s (Very Slow)"
    }
    ELSE {
        Write-Host " Random Write Results:"$RandomWriteMBs.ToString().PadLeft(4,' ') "MB/s (Extremely Slow)"
    }
   


    $Sequential1MBRead = & "$ExeFolder\diskspd.exe" -b1M -d10 -t1 -O8 -s -W2 -C2 -w0 -Z -c1G -Su "$ExeFolder\test.dat"
    $Sequential1MBReadResults = $Sequential1MBRead[-8] | convertfrom-csv -Delimiter "|" -Header Bytes,IO,Mib,IOPS,File | Select-Object IO,MIB,IOPs
    
    [int]$SequentialReadMBs = $Sequential1MBReadResults.Mib

    IF ($SequentialReadMBs -gt 2500) {
        Write-Host " Sequential Read Results:"$SequentialReadMBs.ToString().PadLeft(4,' ') "MB/s (Crazy Fast)"
    }
    ELSEIF ($SequentialReadMBs -gt 1500) {
        Write-Host " Sequential Read Results:"$SequentialReadMBs.ToString().PadLeft(4,' ') "MB/s (Extremely Fast)"
    }
    ELSEIF ($SequentialReadMBs -gt 750) {
        Write-Host " Sequential Read Results:"$SequentialReadMBs.ToString().PadLeft(4,' ') "MB/s (Very Fast)"
    }
    ELSEIF ($SequentialReadMBs -gt 350) {
        Write-Host " Sequential Read Results:"$SequentialReadMBs.ToString().PadLeft(4,' ') "MB/s (Fast)"
    }
    ELSEIF ($SequentialReadMBs -gt 175) {
        Write-Host " Sequential Read Results:"$SequentialReadMBs.ToString().PadLeft(4,' ') "MB/s (Good)"
    }
    ELSEIF ($SequentialReadMBs -gt 100) {
        Write-Host " Sequential Read Results:"$SequentialReadMBs.ToString().PadLeft(4,' ') "MB/s (Acceptable)"
    }
    ELSEIF ($SequentialReadMBs -gt 60) {
        Write-Host " Sequential Read Results:"$SequentialReadMBs.ToString().PadLeft(4,' ') "MB/s (Slow)"
    }
    ELSEIF ($SequentialReadMBs -gt 30) {
        Write-Host " Sequential Read Results:"$SequentialReadMBs.ToString().PadLeft(4,' ') "MB/s (Very Slow)"
    }
    ELSE {
        Write-Host " Sequential Read Results:"$SequentialReadMBs.ToString().PadLeft(4,' ') "MB/s (Extremely Slow)"
    }
  

    ## Sequential Write
    $Sequential1MBWrite = & "$ExeFolder\diskspd.exe" -b1M -d10 -t1 -O8 -s -W2 -C2 -w100 -Z -c1G -Su "$ExeFolder\test.dat"
    $Sequential1MBWriteResults = $Sequential1MBWrite[-15] | convertfrom-csv -Delimiter "|" -Header Bytes,IO,Mib,IOPS,File | Select-Object IO,MIB,IOPs
    
    [int]$SequentialWriteMBs = $Sequential1MBWriteResults.Mib

    IF ($SequentialWriteMBs -gt 2500) {
        Write-Host "Sequential Write Results:"$SequentialWriteMBs.ToString().PadLeft(4,' ') "MB/s (Crazy Fast)"
    }
    ELSEIF ($SequentialWriteMBs -gt 1500) {
        Write-Host "Sequential Write Results:"$SequentialWriteMBs.ToString().PadLeft(4,' ') "MB/s (Extremely Fast)"
    }
    ELSEIF ($SequentialWriteMBs -gt 750) {
        Write-Host "Sequential Write Results:"$SequentialWriteMBs.ToString().PadLeft(4,' ') "MB/s (Very Fast)"
    }
    ELSEIF ($SequentialWriteMBs -gt 350) {
        Write-Host "Sequential Write Results:"$SequentialWriteMBs.ToString().PadLeft(4,' ') "MB/s (Fast)"
    }
    ELSEIF ($SequentialWriteMBs -gt 175) {
        Write-Host "Sequential Write Results:"$SequentialWriteMBs.ToString().PadLeft(4,' ') "MB/s (Good)"
    }
    ELSEIF ($SequentialWriteMBs -gt 100) {
        Write-Host "Sequential Write Results:"$SequentialWriteMBs.ToString().PadLeft(4,' ') "MB/s (Acceptable)"
    }
    ELSEIF ($SequentialWriteMBs -gt 60) {
        Write-Host "Sequential Write Results:"$SequentialWriteMBs.ToString().PadLeft(4,' ') "MB/s (Slow)"
    }
    ELSEIF ($SequentialWriteMBs -gt 30) {
        Write-Host "Sequential Write Results:"$SequentialWriteMBs.ToString().PadLeft(4,' ') "MB/s (Very Slow)"
    }
    ELSE {
        Write-Host "Sequential Write Results:"$SequentialWriteMBs.ToString().PadLeft(4,' ') "MB/s (Extremely Slow)"
    }
  
 

}
Function Get-CPUUsage {

    <#
    .SYNOPSIS
        Measures an average current CPU usage of a period of time.
 
    .DESCRIPTION
 
        PARAMETERS
            -Seconds [int] (Specifies how long to measure average CPU usage, default is 5 seconds)
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-CPUUsage -Seconds 15
 
        Measure average CPU usage over the next 15 seconds.
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    param(
        [Parameter()]
        [int]$Seconds = 5
    )


    [int]$Count = 0
    [int]$CPUUsageTotal = 0

    $Now = Get-Date
    
    WHILE ((Get-Date) -le ($Now).AddSeconds($Seconds)) {
        $CPUUsageTotal += (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue
        $Count++
        Start-Sleep -Milliseconds 250
    }

    return [int]($CPUUsageTotal / $Count)
}
Function Get-AvailableMemoryGBs {

    <#
    .SYNOPSIS
        Returns the available memory in GBs.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Get-AvailableMemoryGBs
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    return ([math]::round((((Get-Counter '\Memory\Available MBytes').CounterSamples.CookedValue)/1Kb),2))

}

Export-ModuleMember -Function Get-CPUScore
Export-ModuleMember -Function Get-PCAge
Export-ModuleMember -Function Get-DiskPerformance
Export-ModuleMember -Function Get-CPUUsage
Export-ModuleMember -Function Get-AvailableMemoryGBs

### ### ==============================================================================================
### ### FIX FUNCTIONS
### ### ==============================================================================================

### ### ### ### Fix-MicrosoftOfficeLogin
### ### ### ### ===============================================

Function Fix-MicrosoftOfficeLogin {

    <#
    .SYNOPSIS
        Fixes various issues with Microsoft Office application logins.
 
    .DESCRIPTION
 
        PARAMETERS
            -DisableAADWAM (Generally Fixes Issues with Office Login Window Not Appearing)
            -ClearAppData (Try This Option If Nothing Else Works, Forces Logoff)
            -ForceLogoff (Required to Use the ClearAppData Parameter)
 
        NOTES
            N/A
 
        TIPS
            N/A
 
    .EXAMPLE
        Fix-MicrosoftOfficeLogin -DisableAADWAM (Disables WAM Related Registry Keys)
 
        This fix is often effective when login prompts are not appearing when the should be.
 
    .EXAMPLE
        Fix-MicrosoftOfficeLogin -ClearAppData -ForceLogoff (Clears WAM Related AppData and Forces Logoff)
 
        This fix can usually resolve most errors. Usually when you log in but it gives the the "something went wrong" with a random error number. This forces the user to log out so make sure to have them save anything they're working on. NOTE: After running this you may receive TPM errors after logging in to office but you will still be able to log in.
 
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    param(
        [Parameter(ParameterSetName = 'DisableAADWAM')]
        [Switch]$DisableAADWAM = $False,

        [Parameter(ParameterSetName = 'ClearAppData')]
        [Switch]$ClearAppData = $False,

        [Parameter(ParameterSetName = 'ClearAppData')]
        [Switch]$ForceLogoff = $False
    )

    function Set-RegistryValueForAllUsers { 
    <#
    .SYNOPSIS
        This function uses Active Setup to create a "seeder" key which creates or modifies a user-based registry value
        for all users on a computer. If the key path doesn't exist to the value, it will automatically create the key and add the value.
    .EXAMPLE
        PS> Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'Setting'; 'Type' = 'String'; 'Value' = 'someval'; 'Path' = 'SOFTWARE\Microsoft\Windows\Something'}
      
        This example would modify the string registry value 'Type' in the path 'SOFTWARE\Microsoft\Windows\Something' to 'someval'
        for every user registry hive.
    .PARAMETER RegistryInstance
         A hash table containing key names of 'Name' designating the registry value name, 'Type' to designate the type
        of registry value which can be 'String,Binary,Dword,ExpandString or MultiString', 'Value' which is the value itself of the
        registry value and 'Path' designating the parent registry key the registry value is in.
    #>
 
    [CmdletBinding()] 
    param ( 
        [Parameter(Mandatory=$true)] 
        [hashtable[]]$RegistryInstance 
    ) 
    try { 
        New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null 
         
        ## Change the registry values for the currently logged on user. Each logged on user SID is under HKEY_USERS
        $LoggedOnSids = (Get-ChildItem HKU: | where { $_.Name -match 'S-\d-\d+-(\d+-){1,14}\d+$' }).PSChildName 
        Write-Host "Found $($LoggedOnSids.Count) logged on user SIDs" 
        foreach ($sid in $LoggedOnSids) { 
            Write-Host -Message "Loading the user registry hive for the logged on SID $sid" 
            foreach ($instance in $RegistryInstance) { 
                ## Create the key path if it doesn't exist
                New-Item -ErrorAction SilentlyContinue -Path ("HKU:\$sid\$($instance.Path)" | Split-Path -Parent) -Name ("HKU:\$sid\$($instance.Path)" | Split-Path -Leaf) | Out-Null 
                ## Create (or modify) the value specified in the param
                Set-ItemProperty -Path "HKU:\$sid\$($instance.Path)" -Name $instance.Name -Value $instance.Value -Type $instance.Type -Force -ErrorAction SilentlyContinue
            } 
        } 
         
        ## Create the Active Setup registry key so that the reg add cmd will get ran for each user
        ## logging into the machine.
        ## http://www.itninja.com/blog/view/an-active-setup-primer
        Write-Host "Setting Active Setup registry value to apply to all other users" 
        foreach ($instance in $RegistryInstance) { 
            ## Generate a unique value (usually a GUID) to use for Active Setup
            $Guid = [guid]::NewGuid().Guid 
            $ActiveSetupRegParentPath = 'HKLM:\Software\Microsoft\Active Setup\Installed Components' 
            ## Create the GUID registry key under the Active Setup key
            New-Item -Path $ActiveSetupRegParentPath -Name $Guid -ErrorAction SilentlyContinue | Out-Null -ErrorAction SilentlyContinue
            $ActiveSetupRegPath = "HKLM:\Software\Microsoft\Active Setup\Installed Components\$Guid" 
            Write-Host "Using registry path '$ActiveSetupRegPath'" 
             
            ## Convert the registry value type to one that reg.exe can understand. This will be the
            ## type of value that's created for the value we want to set for all users
            switch ($instance.Type) { 
                'String' { 
                    $RegValueType = 'REG_SZ' 
                } 
                'Dword' { 
                    $RegValueType = 'REG_DWORD' 
                } 
                'Binary' { 
                    $RegValueType = 'REG_BINARY' 
                } 
                'ExpandString' { 
                    $RegValueType = 'REG_EXPAND_SZ' 
                } 
                'MultiString' { 
                    $RegValueType = 'REG_MULTI_SZ' 
                } 
                default { 
                    throw "Registry type '$($instance.Type)' not recognized" 
                } 
            } 
             
            ## Build the registry value to use for Active Setup which is the command to create the registry value in all user hives
            $ActiveSetupValue = "reg add `"{0}`" /v {1} /t {2} /d {3} /f" -f "HKCU\$($instance.Path)", $instance.Name, $RegValueType, $instance.Value 
            Write-Host -Message "Active setup value is '$ActiveSetupValue'" 
            ## Create the necessary Active Setup registry values
            Set-ItemProperty -Path $ActiveSetupRegPath -Name '(Default)' -Value 'Active Setup Test' -ErrorAction SilentlyContinue
            Set-ItemProperty -Path $ActiveSetupRegPath -Name 'Version' -Value '1' -ErrorAction SilentlyContinue
            Set-ItemProperty -Path $ActiveSetupRegPath -Name 'StubPath' -Value $ActiveSetupValue -ErrorAction SilentlyContinue
        } 
    } catch { 
        Write-Warning -Message $_.Exception.Message 
    } 
}

    IF ($DisableAADWAM -eq $True) {

        IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
             Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
             Return
        }    

        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'DisableAADWAM'; 'Type' = 'DWORD'; 'Value' = '1'; 'Path' = 'Software\Microsoft\Office\16.0\Common\Identity'} 
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'DisableADALatopWAMOverride'; 'Type' = 'DWORD'; 'Value' = '1'; 'Path' = 'Software\Microsoft\Office\16.0\Common\Identity'} 
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'EnableADAL'; 'Type' = 'DWORD'; 'Value' = '1'; 'Path' = 'Software\Microsoft\Office\16.0\Common\Identity'} 

        New-ItemProperty -Path "SOFTWARE\Microsoft\Cryptography\Protect\Providers\df9d8cd0-1501-11d1-8c7a-00c04fc297eb" -Name ProtectionPolicy -Value 1 -ErrorAction SilentlyContinue
        Set-ItemProperty -Path "SOFTWARE\Microsoft\Cryptography\Protect\Providers\df9d8cd0-1501-11d1-8c7a-00c04fc297eb" -Name ProtectionPolicy -Value 1 -ErrorAction SilentlyContinue
        
        Write-Host "DisableAADWAM Successful"
        Write-Host  
    }
       
    IF ($ClearAppData -eq $True -and $ForceLogoff -eq $False) {
        IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
             Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
             Return
        }        

        Write-Warning “You must specify the -ForceLogoff parameter to run the -ClearAppData parameter.”
        Return
    }

    IF ($ClearAppData -eq $True -and $ForceLogoff -eq $True) {

        IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
             Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
             Return
        }        
        
        quser | Select-Object -Skip 1 | ForEach-Object {
            $id = ($_ -split ' +')[-6]
            logoff $id
        }

        While ( (Get-Process -Name Outlook -ErrorAction SilentlyContinue) -ne $null) { Stop-Process -Name Outlook -ErrorAction SilentlyContinue } 
        While ( (Get-Process -Name WinWord -ErrorAction SilentlyContinue) -ne $null) { Stop-Process -Name WinWord -ErrorAction SilentlyContinue } 
        While ( (Get-Process -Name Excel -ErrorAction SilentlyContinue) -ne $null) { Stop-Process -Name Excel -ErrorAction SilentlyContinue } 
        While ( (Get-Process -Name OneDrive -ErrorAction SilentlyContinue) -ne $null) { Stop-Process -Name OneDrive -ErrorAction SilentlyContinue } 
        While ( (Get-Process -Name PowerPnt -ErrorAction SilentlyContinue) -ne $null) { Stop-Process -Name PowerPnt -ErrorAction SilentlyContinue } 
        While ( (Get-Process -Name Teams -ErrorAction SilentlyContinue) -ne $null) { Stop-Process -Name Teams -ErrorAction SilentlyContinue } 

        $TokenSet = @{
                U = [Char[]]'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
                L = [Char[]]'abcdefghijklmnopqrstuvwxyz'
                N = [Char[]]'0123456789'
            }

        $Upper = Get-Random -Count 5 -InputObject $TokenSet.U
        $Lower = Get-Random -Count 5 -InputObject $TokenSet.L
        $Number = Get-Random -Count 5 -InputObject $TokenSet.N
        $StringSet = $Upper + $Lower + $Number
        $Random1 = (Get-Random -Count 10 -InputObject $StringSet) -join ''
        $Upper = Get-Random -Count 5 -InputObject $TokenSet.U
        $Lower = Get-Random -Count 5 -InputObject $TokenSet.L
        $Number = Get-Random -Count 5 -InputObject $TokenSet.N
        $StringSet = $Upper + $Lower + $Number
        $Random2 = (Get-Random -Count 10 -InputObject $StringSet) -join ''

        $Users = Get-Item -Path "C:\Users\*"

        FOREACH ($User in $Users) { 
            $UserFolder = $User.Name
            Rename-Item C:\Users\$UserFolder\AppData\Local\Packages\Microsoft.AAD.BrokerPlugin_cw5n1h2txyewy C:\Users\$UserFolder\AppData\Local\Packages\Microsoft.AAD.BrokerPlugin.bak.$Random1 -ErrorAction SilentlyContinue
            Rename-Item C:\Users\$UserFolder\AppData\Local\Packages\Microsoft.AAD.BrokerPlugin_cw5n1h2txyewy C:\Users\$UserFolder\AppData\Local\Packages\Microsoft.AAD.BrokerPlugin.bak.$Random2 -ErrorAction SilentlyContinue
            Rename-Item C:\Users\$UserFolder\AppData\Local\Packages\Microsoft.AccountsControl_cw5n1h2txyewy C:\Users\$UserFolder\AppData\Local\Packages\Microsoft.AccountsControl.bak.$Random1 -ErrorAction SilentlyContinue
            Rename-Item C:\Users\$UserFolder\AppData\Local\Packages\Microsoft.AccountsControl_cw5n1h2txyewy C:\Users\$UserFolder\AppData\Local\Packages\Microsoft.AccountsControl.bak.$Random2 -ErrorAction SilentlyContinue
        }

        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'DisableAADWAM'; 'Type' = 'DWORD'; 'Value' = '1'; 'Path' = 'Software\Microsoft\Office\16.0\Common\Identity'} 
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'DisableADALatopWAMOverride'; 'Type' = 'DWORD'; 'Value' = '1'; 'Path' = 'Software\Microsoft\Office\16.0\Common\Identity'} 
        Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'EnableADAL'; 'Type' = 'DWORD'; 'Value' = '1'; 'Path' = 'Software\Microsoft\Office\16.0\Common\Identity'} 

        New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive"
        New-ItemProperty -Path "SOFTWARE\Microsoft\Cryptography\Protect\Providers\df9d8cd0-1501-11d1-8c7a-00c04fc297eb" -Name ProtectionPolicy -Value 1
        Set-ItemProperty -Path "SOFTWARE\Microsoft\Cryptography\Protect\Providers\df9d8cd0-1501-11d1-8c7a-00c04fc297eb" -Name ProtectionPolicy -Value 1
    }
}

Export-ModuleMember -Function Fix-MicrosoftOfficeLogin

### ### ==============================================================================================
### ### SEARCH FUNCTIONS
### ### ==============================================================================================

Function Search-EventLog {

    <#
    .SYNOPSIS
        Search the Event Log for Keywords or other parameters.
 
    .DESCRIPTION
 
        PARAMETERS
            -Minutes (int) (Specify the Time in Minutes to Search, Use Only One Time Parameter)
            -Hours (int) (Specify the Time in Hours to Search, Use Only One Time Parameter)
            -Days (int) (Specify the Time in Days to Search, Use Only One Time Parameter)
            -SeverityLevel (Specify Which Severity Level Entries to Search for, Can Specify Multiple)
                Critial
                Error
                Warning
                Information
                All
            -Keywords (String[]) (Specify Keyword(s) to Search For, Can Specify Multiple)
            -EventID (int[]) (Specify EventID(s) to Search For, Can Specify Multiple)
            -IncludeSecurityLog (Use to Include the Security Log in the Search, Will Make the Search Take Longer)
 
        NOTES
            Searching all severity levels and log periods of time can take a while.
 
        TIPS
            N/A
 
    .EXAMPLE
        Search-EventLog
 
        Search for all Critial and Error events within the past two hours.
     
    .EXAMPLE
        Search-EventLog -Days 14 -SeverityLevel Critical,Error -Keywords Adobe,Acrobat
 
        Search for Critical, Error, and Warning messages within the last 14 days that mention 'Adobe' or 'Acrobat'.
 
    .EXAMPLE
        Search-EventLog -Days 90 -SeverityLevel All -Keywords DMAdmin -IncludeSecurityLog
 
        Searches for all events in the past 90 days, including the security log,
 
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


[CmdletBinding(DefaultParameterSetName='Minutes')]
    param(

        [Parameter(ParameterSetName = 'Full')]
        [Parameter(ParameterSetName = 'Minutes')]
        [int]$Minutes = 120,
        
        [Parameter(ParameterSetName = 'Full')]
        [Parameter(ParameterSetName = 'Hours')]
        [int]$Hours = $null,
        
        [Parameter(ParameterSetName = 'Full')]
        [Parameter(ParameterSetName = 'Days')]
        [int]$Days = $null,
                
        [Parameter(ParameterSetName = 'Minutes')]
        [Parameter(ParameterSetName = 'Hours')]
        [Parameter(ParameterSetName = 'Days')]
        [ValidateSet("Critical","Error","Warning","Information","All")]
        [String[]]$SeverityLevel = @("Critical","Error"),

        [Parameter(ParameterSetName = 'Full')]
        [Parameter(ParameterSetName = 'Minutes')]
        [Parameter(ParameterSetName = 'Hours')]
        [Parameter(ParameterSetName = 'Days')]
        [String[]]$Keywords = $null,

        [Parameter(ParameterSetName = 'Full')]
        [Parameter(ParameterSetName = 'Minutes')]
        [Parameter(ParameterSetName = 'Hours')]
        [Parameter(ParameterSetName = 'Days')]
        [String[]]$EventID = $null,


        [Parameter(ParameterSetName = 'Minutes')]
        [Parameter(ParameterSetName = 'Hours')]
        [Parameter(ParameterSetName = 'Days')]
        [switch]$IncludeSecurityLog = $false,

        [Parameter(Mandatory, ParameterSetName = 'Full')]
        [switch]$Full = $false
    )

    [int[]]$SearchIDs = @()
    $Now = Get-Date
    
    [int[]]$Level = @()
    IF ($SeverityLevel.Contains("Critical")) { $Level += 1 }
    IF ($SeverityLevel.Contains("Error")) { $Level += 2 }
    IF ($SeverityLevel.Contains("Warning")) { $Level += 3 }
    IF ($SeverityLevel.Contains("Information")) { $Level += 4 }
    IF ($SeverityLevel.Contains("All")) { $Level = @(0,1,2,3,4,5) }
    IF ($Full -eq $true) { $Level = @(0,1,2,3,4,5) }

    IF ($EventID -ne $null) {
        FOREACH ($Item in $EventID) {
            $SearchIDs += $Item
        }
    }
       
    IF ($Days -gt 0) { $Minutes = $Days * 1440 }
    IF ($Hours -gt 0) { $Minutes = $Hours * 60 }
    $Results = @()
    $Logs = Get-WinEvent -ListLog * -EA SilentlyContinue | Where { $_.RecordCount -ne 0 -and $_.LastWriteTime -gt $Now.AddMinutes(-$Minutes) }
    
    ForEach ($Log in $Logs) {
        IF ($Log.LogName -eq "Windows PowerShell" -and $Full -eq $false) { continue }
        IF ($Log.LogName -eq "Security" -and $IncludeSecurityLog -eq $false) { IF ($Full -eq $false) { continue } }
        IF ($Log.LogName -like "Microsoft-Windows-Ntfs/Operational" -and $Full -eq $false) { continue }
        IF ($Log.LogName -like "Microsoft-Windows-Store/Operational" -and $Full -eq $false) { continue }
        IF ($Log.LogName -like "Microsoft-Windows-StateRepository/Operational" -and $Full -eq $false) { continue }
        IF ($Log.LogName -like "Microsoft-Windows-SmbClient/Connectivity" -and $Full -eq $false) { continue }
        IF ($Log.LogName -like "Microsoft-Windows-PowerShell" -and $Full -eq $false) { continue }
        IF ($Log.LogName -like "Microsoft-Windows-Storage-Storport/Operational" -and $Full -eq $false) { continue }
        IF ($Log.LogName -like "Microsoft-Windows-Storage-Storport/Health" -and $Full -eq $false) { continue }
        IF ($Log.LogName -like "Microsoft-Windows-PowerShell/Operational" -and $Full -eq $false) { continue }
        IF ($Log.LogName -like "Microsoft-Windows-LiveId/Operational" -and $Full -eq $false) { continue } 

        IF ($EventID -eq $null) { $EventInfo = Get-WinEvent -FilterHashtable @{logname = $Log.LogName; Level = @($Level); StartTime = $Now.AddMinutes(-$minutes)} -ErrorAction SilentlyContinue }
        ELSE { $EventInfo = Get-WinEvent -FilterHashtable @{logname = $Log.LogName; Level = @($Level); ID = @($SearchIDs); StartTime = $Now.AddMinutes(-$minutes)} -ErrorAction SilentlyContinue }
          
                
        FOREACH ($Event in $EventInfo) {
            
            IF ($Keywords -ne $null) {
                $Found = $false
                FOREACH ($Keyword in $Keywords) {
                    IF ($Event.Message -like "*$Keyword*") { $Found = $true }
                }
                IF ($Found -eq $false) { continue }
            }

            $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                Message = $Event.Message
                Id = $Event.ID 
                Version = $Event.Version
                Qualifiers = $Event.Qualifiers
                Level = $Event.Level
                Task = $Event.Task
                Opcode = $Event.Opcode
                Keywords = $Event.Keywords
                RecordId = $Event.RecordId
                ProviderName = $Event.ProviderName
                ProviderId = $Event.ProviderId
                LogName = $Event.LogName 
                ProcessId = $Event.ProcessId
                ThreadId = $Event.ThreadId
                MachineName = $Event.MachineName
                UserId = $Event.UserId
                TimeCreated = $Event.TimeCreated
                ActivityId = $Event.ActivityId
                RelatedActivityId = $Event.RelatedActivityId
                ContainerLog = $Event.ContainerLog
                MatchedQueryIds = $Event.MatchedQueryIds
                Bookmark = $Event.Bookmark
                LevelDisplayName = $Event.LevelDisplayName
                OpcodeDisplayName = $Event.OpcodeDisplayName
                KeywordsDisplayNames = $Event.KeywordsDisplayNames
                Properties = $Event.Properties
            }
        }
    }
    return $Results | Select ID,LogName,LevelDisplayName,TimeCreated,Message | Format-List
}
Function Search-AppData {

    [CmdletBinding(DefaultParameterSetName='None')]
    param(
        
        [Parameter(Mandatory)]
        [Parameter(ParameterSetName = 'None')]
        [Parameter(ParameterSetName = 'Rename')]
        [Parameter(ParameterSetName = 'Delete')]
        [string[]]$Keyword = "",
        
        [Parameter(ParameterSetName = 'None')]
        [Parameter(ParameterSetName = 'Rename')]
        [Parameter(ParameterSetName = 'Delete')]
        [switch]$ExactMatch = $false,

        [Parameter(ParameterSetName = 'Rename')]
        [switch]$Rename = $false,

        [Parameter(ParameterSetName = 'Delete')]
        [switch]$Delete = $false
    )    

    $ActionTaken = "None"
    IF ($Rename -eq $true) { $ActionTaken = "Rename" }
    IF ($Delete -eq $true) { $ActionTaken = "Delete" }
    
    $Folders = Get-ChildItem -Path $env:APPDATA,$env:LOCALAPPDATA -Directory
    $Results = @()
    FOREACH ($Folder in $Folders) {
        IF ($Folder.Name -like "*_bak_*") { continue }
        FOREACH ($Item in $Keyword) {
            IF ($ExactMatch -eq $false) {
                IF ($Folder -Like "*$Item*") {
                    IF ($Delete -eq $true) {
                        TRY {
                            Remove-Item -Path $Folder.FullName -Force -ErrorAction SilentlyContinue
                            $ActionResult = "Successful"
                            IF ((Get-Item -Path $Folder.FullName -ErrorAction SilentlyContinue) -ne $null) {
                                $ActionResult = "Failed"
                            }
                        }
                        CATCH {
                            IF ((Get-Item -Path $Folder.FullName) -ne $null) {
                                $ActionResult = "Failed"
                            }
                            ELSE { $ActionResult = "Successful" }
                        }
                    }
                    ELSEIF ($Rename -eq $true) {
                        $Now = Get-Date
                        $NewName = $Folder.FullName
                        $NewName += "_bak_$($Now.ToString('yyy_MM_dd_HH_mm_ss'))"
                        
                        TRY {
                            Rename-Item -Path $Folder.FullName -NewName $NewName -Force -ErrorAction SilentlyContinue
                            $ActionResult = "Successful"
                            IF ((Get-Item -Path $Folder.FullName -ErrorAction SilentlyContinue) -ne $null) {
                                $ActionResult = "Failed"
                            }
                        }
                        CATCH {
                            IF ((Get-Item -Path $Folder.FullName -ErrorAction SilentlyContinue) -ne $null) {
                                $ActionResult = "Failed"
                            }
                            ELSE { $ActionResult = "Successful" }
                        }
                    }
                    ELSE { $ActionResult = "N/A" }
                    
                    $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                        FolderName = $Folder.Name
                        FolderPath = $Folder.FullName 
                        RequestedAction = $ActionTaken
                        ActionResult = $ActionResult
                    }
                    break
                }
            }
            ELSEIF ($ExactMatch -eq $true) {
                IF ($Folder -Like "$Item") {
                    IF ($Delete -eq $true) {
                        TRY {
                            Remove-Item -Path $Folder.FullName -Force -ErrorAction SilentlyContinue
                            $ActionResult = "Successful"
                            IF ((Get-Item -Path $Folder.FullName -ErrorAction SilentlyContinue) -ne $null) {
                                $ActionResult = "Failed"
                            }
                        }
                        CATCH {
                            IF ((Get-Item -Path $Folder.FullName -ErrorAction SilentlyContinue) -ne $null) {
                                $ActionResult = "Failed"
                            }
                            ELSE { $ActionResult = "Successful" }
                        }
                    }
                    ELSEIF ($Rename -eq $true) {
                        $Now = Get-Date
                        $NewName = $Folder.FullName
                        $NewName += "_bak_$($Now.ToString('yyy_MM_dd_HH_mm_ss'))"
                        
                        TRY {
                            Rename-Item -Path $Folder.FullName -NewName $NewName -Force -ErrorAction SilentlyContinue
                            $ActionResult = "Successful"
                            IF ((Get-Item -Path $Folder.FullName -ErrorAction SilentlyContinue) -ne $null) {
                                $ActionResult = "Failed"
                            }
                        }
                        CATCH {
                            IF ((Get-Item -Path $Folder.FullName -ErrorAction SilentlyContinue) -ne $null) {
                                $ActionResult = "Failed"
                            }
                            ELSE { $ActionResult = "Successful" }
                        }
                    }
                    ELSE { $ActionResult = "N/A" }
                    $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                        FolderName = $Folder.Name
                        FolderPath = $Folder.FullName
                        RequestedAction = $ActionTaken
                        ActionResult = $ActionResult
                    }
                    break
                }  
            } 
        }
    }
    FOREACH ($Result in $Results) {
        IF ($Result.ActionResult -eq "Failed") {
            Write-Host ""
            Write-Warning "$ActionTaken Failed: Verifiy the Associated Application is Not Running"
        }
    }

    return $Results | Select FolderName, FolderPath, RequestedAction, ActionResult
}

Export-ModuleMember -Function Search-EventLog
Export-ModuleMember -Function Search-AppData

### ### ==============================================================================================
### ### REPORT FUNCTIONS
### ### ==============================================================================================

Function Report-PCPerformance {

    <#
    .SYNOPSIS
        Generates PC performance summary report.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            Reports on a computer's performance.
            Looks up CPU Score.
            Lists RAM, total and in-use amount.
            Runs a disk benchmark.
 
        TIPS
            Use to help determine is PC slowness is due hardware.
 
    .EXAMPLE
        Report-PCSummary
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    $ProcessorName = Get-ProcessorName
    [int]$CPUScore = Get-CPUScore
    $CPURating = $null
    IF ($CPUScore -gt 25000) { $CPURating = "Very Fast" }
    ELSEIF ($CPUScore -gt 18000) { $CPURating = "Fast" }
    ELSEIF ($CPUScore -gt 12000) { $CPURating = "Good" }
    ELSEIF ($CPUScore -gt 8000) { $CPURating = "Acceptable" }
    ELSEIF ($CPUScore -gt 6000) { $CPURating = "Slow" }
    ELSEIF ($CPUScore -gt 4000) { $CPURating = "Very Slow" }
    ELSE { $CPURating = "Extremely Slow" }

    [int]$TotalRAM = Get-RAMGBsInstalled
    $RAMRating = $null
    IF ($TotalRAM -gt 39) { $RAMRating = "Very High" }
    ELSEIF ($TotalRAM -gt 31) { $RAMRating = "High" }
    ELSEIF ($TotalRAM -gt 23) { $RAMRating = "Good" }
    ELSEIF ($TotalRAM -gt 15) { $RAMRating = "Acceptable" }
    ELSEIF ($TotalRAM -gt 7) { $RAMRating = "Low" }
    ELSEIF ($TotalRAM -gt 5) { $RAMRating = "Very Low" }
    ELSE { $RAMRating = "Extremely Low" }

    $PCAge = Get-PCAge
    $CPUUsage = Get-CPUUsage
    $AvailableMemoryGBs = Get-AvailableMemoryGBs
    $DriveType = Get-OSDriveType

    $WiredConnection = Get-WiredConnection
    $WiredLinkSpeed = Get-WiredLinkSpeed
    $WiFiConnection = Get-WiFiConnection
    $WiFiLinkSpeed = Get-WiFiLinkSpeed
    $WiFiSignalStrength = Get-WiFiSignalStrength

    Write-Host ""
    Write-Host " General Information"
    Write-Host "============================================="
    Write-Host "Approximate Age:".PadLeft(25) $PCAge
    Write-Host ""
    Write-Host " CPU Information"
    Write-Host "============================================="
    Write-Host "CPU Model:".PadLeft(25) $ProcessorName
    Write-Host "CPU Score:".PadLeft(25) $CPUScore
    Write-Host "CPU Rating:".PadLeft(25) $CPURating
    Write-Host "Current Usage:".PadLeft(25) $CPUUsage"%"
    Write-Host ""
    Write-Host " RAM Information"
    Write-Host "============================================="
    Write-Host "Total RAM:".PadLeft(25) $TotalRAM "GB"
    Write-Host "RAM Rating:".PadLeft(25) $RAMRating
    Write-Host "Available Memory:".PadLeft(25) $AvailableMemoryGBs "GBs"
    Write-Host ""
    Write-Host " Network Information"
    Write-Host "============================================="
    Write-Host "Wired Connection".PadLeft(25) $WiredConnection
    Write-Host "Wired Link Speed:".PadLeft(25) $WiredLinkSpeed
    Write-Host "WiFi Connection:".PadLeft(25) $WiFiConnection
    Write-Host "WiFi Link Speed:".PadLeft(25) $WiFiLinkSpeed
    Write-Host "WiFi Signal Strength:".PadLeft(25) $WiFiSignalStrength
    Write-Host ""
    Write-Host " Disk Information"
    Write-Host "============================================="
    Write-Host "Drive Type:".PadLeft(25) $DriveType
    Get-DiskPerformance
    Write-Host ""
}
Function Report-PCSummary {

    <#
    .SYNOPSIS
        Generates PC summary report.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            N/A
 
        TIPS
            Useful for assisting with PC replacements.
            Determine it computer has extra monitors or peripherals that may take extra time to configure.
 
    .EXAMPLE
        Report-PCSummary
     
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    Write-Host ""
    Write-Host "Computer Information"
    Write-Host "============================"
    $env:COMPUTERNAME
    Get-OperatingSystemName
    Get-EnclosureType
    Get-ProcessorName
    Write-Host ""
    Write-Host ""
    Write-Host "RAM Information"
    Write-Host "============================"
    Get-RAMSlots
    Write-Host ""
    Write-Host ""
    Write-Host "Network Adapters"
    Write-Host "============================" -NoNewline
    Get-RealNetworkAdapters | Format-Table -HideTableHeaders
    Write-Host "Display Adapters"
    Write-Host "============================" -NoNewline
    Get-VideoDevices | Format-Table -HideTableHeaders
    Write-Host "Monitors"
    Write-Host "============================"
    Get-MonitorInformation | Format-Table -HideTableHeaders
    Write-Host
    Write-Host
    Write-Host "USB Printers"
    Write-Host "============================" -NoNewline
    $Results = Get-USBPrinters | Format-Table -HideTableHeaders
    IF ($Results -ne $null) { $Results }
    ELSE { Write-Host ""; Write-Host "None Found"; Write-Host ""; Write-Host "" }
    Write-Host "USB Cameras"
    Write-Host "============================" -NoNewline
    $Results = Get-USBCameras | Format-Table -HideTableHeaders
    IF ($Results -ne $null) { $Results }
    ELSE { Write-Host ""; Write-Host "None Found"; Write-Host ""; Write-Host "" }
    Write-Host "Document Scanners (Includes Network Connected)"
    Write-Host "============================" -NoNewline
    $Results = Get-DocumentScanners | Format-Table -HideTableHeaders
    IF ($Results -ne $null) { $Results }
    ELSE { Write-Host ""; Write-Host "None Found"; Write-Host ""; Write-Host "" }
    Write-Host "Installed Applications"
    Write-Host "============================" -NoNewline
    Get-InstalledApplications | Format-Table -HideTableHeaders
}
Function Report-NTFSPermissions {

    <#
    .SYNOPSIS
        Audits NTFS permissions.
 
    .DESCRIPTION
 
        PARAMETERS
            -Paths (String[]) (Specify the Path(s) to be Audited, Can Specify Multiple. Subfolders are Included.)
            -IncludeInherited (Use If You Want to Audit Inherited Permissions, Otherwise Explict Permissions Audited Only)
            -IgnoreEveryone (Use If You Do Not Want to Audit 'Everyone' Group Permissions)
            -IgnoreUsers (Use if You Do Not Want to Audit 'Users' Groups Permissions)
            -Identities (String[]) (Specify the Users\Group(s) to be Audited, If Not Specified 'Everyone' and 'Users' Groups are Audited)
            -PermissionLevel (String[]) (Specify the Permission Level(s) to be Audited, Otherwise All Will Be)
 
        NOTES
            You can audit multiple paths\drives in one command.
            Auditing large numbers of folders may take a long time.
            Auditing entire drives on slow storage may take a very long time. Hours or even days.
            After collecting folder data, the script will try to estimate how long it will take to finish the audit.
 
        TIPS
            You can use the command to help enforce NTFS security standards. For example, if you have a standard to never use the everyone group in NTFS permissions you can use a tool such as CW Automate to run this command and create a ticket if any instances of the everyone group are found.
 
    .EXAMPLE
        Audit-NTFSPermissions -Path `"C:\`",`"D:\`"
         
        Audits Explict Entries for 'Everyone' and 'Users' on the C:\ and D:\ Paths
     
    .EXAMPLE
        Audit-NTFSPermissions -Path `"D:\`" -IgnoreEveryone -IncludeInherited
         
        Audits All Entries for 'Users' in the D:\ Path
         
    .EXAMPLE
        Audit-NTFSPermissions -Path `"D:\`" -Identity `"RW -`",`"RO - `"
         
        Audits All Entries for any user or group containing 'RW - ' or 'RO - ' in the D:\ Path
 
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>


    [CmdletBinding(DefaultParameterSetName='StandardAudit')]
    param(
        [Parameter(Mandatory,ParameterSetName = 'StandardAudit')]
        [Parameter(Mandatory,ParameterSetName = 'CustomAudit')]
        [string[]]$Path = "C:\",

        [Parameter(Mandatory,ParameterSetName = 'CustomAudit')]
        [string[]]$Identity = $null,

        [Parameter(ParameterSetName = 'CustomAudit')]
        [ValidateSet("Deny","ReadOnly","ReadWrite","FullControl")]
        [String[]]$PermissionLevel = @("Deny","ReadOnly","ReadWrite","FullControl"),
             
        [Parameter(ParameterSetName = 'StandardAudit')]
        [Switch]$IgnoreEveryone = $False,

        [Parameter(ParameterSetName = 'StandardAudit')]
        [Switch]$IgnoreUsers = $False,              

        [Parameter(ParameterSetName = 'StandardAudit')]
        [Parameter(ParameterSetName = 'CustomAudit')]
        [Switch]$IncludeInherited = $False
    )
        
    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }

    IF ($Identity -ne $null) {
        $IgnoreUsers = $true
        $IgnoreEveryone = $true
    }


    CLS
    Write-Host "Collecting Folder Data..."
    $Folders = $null

    FOREACH ($Item in $Path) {
        $Folders += Get-ChildItem -Path $Item -Recurse -Directory -ErrorAction SilentlyContinue
    }
      
    $ProgressCount = 0
    $AuditFindings = @()
    $StartTime = $StartTime = $(Get-Date)
    FOREACH ($Folder in $Folders) {
        $ProgressCount++
        [int]$PercentProgress = $ProgressCount / $Folders.Count * 100
        
        IF ($ProgressCount -eq 1) {
            CLS
            Write-Host "Analyzing NTFS Permissions..."$PercentProgress"%"
            Write-Host "Estimated Time to Finish: Calculating..."
        }
        IF ($ProgressCount % 350 -eq 0 ) {
            CLS
            $TimeElapsed = $(Get-Date) - $StartTime
            $Factor = $Folders.Count / $ProgressCount
            $EstimatedSeconds = $TimeElapsed.TotalSeconds * $Factor - $TimeElapsed.TotalSeconds
            [int]$EstimatedMinutes = $EstimatedSeconds / 60 + 1
            
            Write-Host "Analyzing NTFS Permissions..."$PercentProgress"%"
            IF ($EstimatedSeconds -lt 45) { Write-Host "Estimated Time to Finish: < 1 Minute" }
            ELSEIF ($EstimatedMinutes -eq 1) { Write-Host "Estimated Time to Finish: "$EstimatedMinutes" Minute" }
            ELSE { Write-Host "Estimated Time to Finish: "$EstimatedMinutes" Minutes" }
        }
        

        $ACL = Get-ACL -Path $Folder.FullName -ErrorAction SilentlyContinue

        FOREACH ($AccessIdentity in $ACL.Access) {

            
             
            IF ($AccessIdentity.IdentityReference.Value -like "*Everyone*" -and $IgnoreEveryone -eq $false) {
                IF ($AccessIdentity.AccessControlType -like "*Deny*") { $PermissionLabel = "Deny" }
                ELSEIF ($AccessIdentity.FileSystemRights -like "*FullControl*") { $PermissionLabel = "FullControl" }
                ELSEIF ($AccessIdentity.FileSystemRights -like "*Modify*") { $PermissionLabel = "ReadWrite" }
                ELSEIF ($AccessIdentity.FileSystemRights -like "*ReadAndExecute*") { $PermissionLabel = "ReadOnly" }
                ELSE { $PermissionLabel = "Other" }

                IF ($AccessIdentity.IsInherited -eq $true -and $IncludeInherited -eq $true) { $AuditFindings += "Inherited - $PermissionLabel - $AccessIdentity.IdentityReference.Value - "+$Folder.FullName }
                IF ($AccessIdentity.IsInherited -eq $false) { $AuditFindings += "Explicit - $PermissionLabel - Everyone - "+$Folder.FullName }
            }
            
            IF ($AccessIdentity.IdentityReference.Value -like "*\Domain Users*" -and $IgnoreUsers -eq $false) {
                IF ($AccessIdentity.AccessControlType -like "*Deny*") { $PermissionLabel = "Deny" }
                ELSEIF ($AccessIdentity.FileSystemRights -like "*FullControl*") { $PermissionLabel = "FullControl" }
                ELSEIF ($AccessIdentity.FileSystemRights -like "*Modify*") { $PermissionLabel = "ReadWrite" }
                ELSEIF ($AccessIdentity.FileSystemRights -like "*ReadAndExecute*") { $PermissionLabel = "ReadOnly" }
                ELSE { $PermissionLabel = "Other" }

                IF ($AccessIdentity.IsInherited -eq $true -and $IncludeInherited -eq $true) { $AuditFindings += "Inherited - $PermissionLabel - $AccessIdentity.IdentityReference.Value - "+$Folder.FullName }
                IF ($AccessIdentity.IsInherited -eq $false) { $AuditFindings += "Explicit - $PermissionLabel - Domain Users - "+$Folder.FullName }
            }
            
            IF ($AccessIdentity.IdentityReference.Value -like "*\Users*" -and $IgnoreUsers -eq $false) {
                IF ($AccessIdentity.AccessControlType -like "*Deny*") { $PermissionLabel = "Deny" }
                ELSEIF ($AccessIdentity.FileSystemRights -like "*FullControl*") { $PermissionLabel = "FullControl" }
                ELSEIF ($AccessIdentity.FileSystemRights -like "*Modify*") { $PermissionLabel = "ReadWrite" }
                ELSEIF ($AccessIdentity.FileSystemRights -like "*ReadAndExecute*") { $PermissionLabel = "ReadOnly" }
                ELSE { $PermissionLabel = "Other" }

                IF ($AccessIdentity.IsInherited -eq $true -and $IncludeInherited -eq $true) { $AuditFindings += "Inherited - $PermissionLabel - $AccessIdentity.IdentityReference.Value - "+$Folder.FullName }
                IF ($AccessIdentity.IsInherited -eq $false) { $AuditFindings += "Explicit - $PermissionLabel - Domain Users - "+$Folder.FullName }
            }

            IF ($Identity -ne $null) {
                FOREACH ($Entry in $Identity) {
                    IF ($AccessIdentity.IdentityReference.Value -like "*$Entry*") {
                        FOREACH ($Permission in $PermissionLevel) {
                            IF ($AccessIdentity.AccessControlType -like "*Deny*" -and $Permission -eq "Deny") {
                                IF ($AccessIdentity.IsInherited -eq $true -and $IncludeInherited -eq $true) { $AuditFindings += "Inherited - Deny - "+$AccessIdentity.IdentityReference.Value+" - "+$Folder.FullName }
                                IF ($AccessIdentity.IsInherited -eq $false) { $AuditFindings += "Explicit - Deny - "+$AccessIdentity.IdentityReference.Value+" - "+$Folder.FullName }
                                continue
                            }
                            IF ($AccessIdentity.FileSystemRights -like "*FullControl*" -and $Permission -eq "FullControl" -and $AccessIdentity.AccessControlType -like "*Allow*") {
                                IF ($AccessIdentity.IsInherited -eq $true -and $IncludeInherited -eq $true) { $AuditFindings += "Inherited - Full Control - "+$AccessIdentity.IdentityReference.Value+" - "+$Folder.FullName }
                                IF ($AccessIdentity.IsInherited -eq $false) { $AuditFindings += "Explicit - Full Control - "+$AccessIdentity.IdentityReference.Value+" - "+$Folder.FullName }
                                continue
                            }
                            IF ($AccessIdentity.FileSystemRights -like "*Modify*" -and $Permission -eq "ReadWrite" -and $AccessIdentity.AccessControlType -like "*Allow*") {
                                IF ($AccessIdentity.IsInherited -eq $true -and $IncludeInherited -eq $true) { $AuditFindings += "Inherited - ReadWrite - "+$AccessIdentity.IdentityReference.Value+" - "+$Folder.FullName }
                                IF ($AccessIdentity.IsInherited -eq $false) { $AuditFindings += "Explicit - Write - "+$AccessIdentity.IdentityReference.Value+" - "+$Folder.FullName }
                                continue
                            }
                            IF ($AccessIdentity.FileSystemRights -like "*ReadAndExecute*" -and $Permission -eq "ReadOnly" -and $AccessIdentity.AccessControlType -like "*Allow*") {
                                IF ($AccessIdentity.IsInherited -eq $true -and $IncludeInherited -eq $true) { $AuditFindings += "Inherited - ReadOnly - "+$AccessIdentity.IdentityReference.Value+" - "+$Folder.FullName }
                                IF ($AccessIdentity.IsInherited -eq $false) { $AuditFindings += "Explicit - ReadOnly - "+$AccessIdentity.IdentityReference.Value+" - "+$Folder.FullName }
                                continue
                            }
                        }
                    }
                }
            }
        }
    }
    CLS
    Write-Host ""
    Write-Host "NTFS Permissions Found"
    Write-Host "==========================="  
    $AuditFindings
    Write-Host ""
    Write-Host ""
}
Function Report-ADGroupMembership {

    <#
    .SYNOPSIS
        Audits AD group membership.
 
    .DESCRIPTION
 
        PARAMETERS
            -Group (String[]) (Specify the Group(s) to be Audited, Can Specify Multiple, Wildcard Match)"
            -ExactMatch (Use If You Want to Audit Exact Match Only, No Wildcard Search of Groups)"
             
        NOTES
            You can audit multiple paths\drives in one command.
            Auditing large numbers of folders may take a long time.
            Auditing entire drives on slow storage may take a very long time. Hours or even days.
            After collecting folder data, the script will try to estimate how long it will take to finish the audit.
 
        TIPS
            You can audit multiple groups in one command.
            This command will only work if run on a DC or a computer with RSAT installed and connected to a DC.
    .EXAMPLE
        Audit-ADGroupMembership -Group `"RO -`",`"RW -`"
         
        Audits Membership of All Group with `"RO -`" or `"RW -`" in the Name
             
    .EXAMPLE
        Audit-ADGroupMembership -Paths `"RW - Human Resources`" -ExactMatch
         
        Audits the Membership of Group Exactly Matching RW - `"Human Resources`"
 
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>

    
    [CmdletBinding(DefaultParameterSetName='Audit')]
    param(
        [Parameter(Mandatory,ParameterSetName = 'Audit')]
        [Parameter(Mandatory,ParameterSetName = 'Compare')]
        [string[]]$Group = $null,

        [Parameter(ParameterSetName = 'Audit')]
        [Parameter(ParameterSetName = 'Compare')]
        [Switch]$ExactMatch = $false,

        [Parameter(ParameterSetName = 'Audit')]
        [Parameter(Mandatory,ParameterSetName = 'Compare')]
        [string]$SaveFileName = $null,

        [Parameter(ParameterSetName = 'Compare')]
        [Switch]$Compare = $false
    )
    
    ### Check for Administrator Access
    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }

    ### Check Save File Exists
    IF ($Compare -ne $false) {
        [string]$CSVCheck = "C:\IntegrisPowerShellTemp\Audit-ADGroupMembership\Saves\"
        $CSVCheck += $SaveFileName
        IF($CSVCheck.Substring($CSVCheck.Length-4,4) -ne ".csv") { $CSVCheck += ".csv" }
        IF((Get-Item $CSVCheck) -eq $null) {
            Write-Warning “The save file you entered was not found.`nPlease re-run this command with a valid save file in C:\IntegrisPowerShellTemp\Audit-ADGroupMembership\Saves.”
            Return
        }
    }
    
    #Write-Host ""
    $EmptyString = ""
    $DividerLength = 50
    $NamePadding = 30
    $UsernamePadding = 25
    $Results = @()
    $CompareResultsOut = @()

    IF ($ExactMatch -eq $true) {
        FOREACH ($Entry in $Group){
            $Membership = $null
            try { $Membership = Get-ADGroupMember -Identity $Entry -ErrorAction SilentlyContinue } catch { }
            IF ($Membership -eq $null) { continue }
            #Write-Host $Entry.PadLeft(($DividerLength - $Entry.Length)/2+$Entry.Length," ")
            #Write-Host $EmptyString.tostring().Padleft($DividerLength,'=')
            FOREACH ($Member in $Membership) {
                #Write-Host $Member.Name.PadRight($NamePadding,' ') -NoNewline
                #Write-Host $Member.SAMAccountName
                ### Output Results
                $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                    GroupName = $Membership
                    UserName = $Member.SAMAccountName
                    FullName = $Member.Name
                 }
            }
            #Write-Host ""
            #Write-Host ""
        }
    }

    IF ($ExactMatch -eq $false) {
        FOREACH ($Entry in $Group){

            try { $GroupSearch = Get-ADGroup -Filter * -ErrorAction SilentlyContinue | Where-Object { $_.Name -like "*$Entry*" } } catch { }

            FOREACH ($GroupEntry in $GroupSearch){
                $Membership = $null
                $Membership = Get-ADGroupMember -Identity $GroupEntry.Name -ErrorAction SilentlyContinue
                IF ($Membership -eq $null) { continue }
                #Write-Host $GroupEntry.Name.PadLeft(($DividerLength - $GroupEntry.Name.Length)/2+$GroupEntry.Name.Length," ")
                #Write-Host $EmptyString.tostring().Padleft($DividerLength,'=')
                FOREACH ($Member in $Membership) {
                    #Write-Host $Member.Name.PadRight($NamePadding,' ') -NoNewline
                    #Write-Host $Member.SAMAccountName
                    ### Output Results
                    $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                        GroupName = $GroupEntry.Name
                        UserName = $Member.SAMAccountName
                        FullName = $Member.Name
                    }
                }
                #Write-Host ""
                #Write-Host ""
            }
        }
    }

    IF ($Compare -eq $true) {
        [string]$ImportPath = "C:\IntegrisPowerShellTemp\Audit-ADGroupMembership\Saves\"
        $ImportPath += $SaveFileName
        IF($ImportPath.Substring($ImportPath.Length-4,4) -ne ".csv") { $ImportPath += ".csv" }
        $ImportResults = Import-CSV $ImportPath
        $CompareResults = Compare-Object -ReferenceObject $Results -DifferenceObject $ImportResults -Property GroupName,UserName,FullName
        FOREACH ($Item in $CompareResults) {
            $CompareResultsOut += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                GroupName = $Item.GroupName
                UserName = $Item.UserName
                FullName = $Item.FullName
                ChangeType = $Item.SideIndicator
            }
            FOREACH ($Item in $CompareResultsOut) {
                IF ($Item.ChangeType -eq "=>") { $Item.ChangeType = "Removed" }
                IF ($Item.ChangeType -eq "<=") { $Item.ChangeType = "Added" }
            }
        } 
        MKDir "C:\IntegrisPowerShellTemp\Audit-ADGroupMembership\Comparisons\" -ErrorAction SilentlyContinue | Out-Null
        [string]$ComparePath = "C:\IntegrisPowerShellTemp\Audit-ADGroupMembership\Comparisons\"
        $ComparePath += $SaveFileName
        IF($ComparePath.Substring($ComparePath.Length-4,4) -ne ".csv") { $ComparePath += ".csv" }
        ### Check If File Already Exists, If So Rename It
        IF((Get-Item $ComparePath -ErrorAction SilentlyContinue) -ne $null) { 
            $CreatedDate = Get-Item -Path $ComparePath
            $NewName = $ComparePath.Replace(".csv","")
            $NewName += $CreatedDate.LastWriteTime.ToString(" yyy_MM_dd h_mm_s")
            $NewName += ".csv"
            Rename-Item -Path $ComparePath -NewName $NewName -Force   
        }
         $Results | Export-CSV $ComparePath -Force
    }

    
    IF ($SaveFileName -ne $null) {
        MKDir "C:\IntegrisPowerShell\Audit-ADGroupMembership\Saves\" -ErrorAction SilentlyContinue | Out-Null
        [string]$ExportPath = "C:\IntegrisPowerShell\Audit-ADGroupMembership\Saves\"
        $ExportPath += $SaveFileName
        IF($ExportPath.Substring($ExportPath.Length-4,4) -ne ".csv") { $ExportPath += ".csv" }
        ### Check If File Already Exists, If So Rename It
        IF((Get-Item $ExportPath -ErrorAction SilentlyContinue) -ne $null) { 
            $CreatedDate = Get-Item -Path $ExportPath
            $NewName = $ExportPath.Replace(".csv","")
            $NewName += $CreatedDate.LastWriteTime.ToString(" yyy_MM_dd h_mm_s")
            $NewName += ".csv"
            Rename-Item -Path $ExportPath -NewName $NewName -Force  
        }
        $Results | Export-CSV $ExportPath -Force
    }
   
    IF ($Compare -eq $true) { return $CompareResultsOut | Select UserName,FullName,GroupName,ChangeType }
    ELSE { return $Results | Select UserName,FullName,GroupName }
}
Function Report-ADUser {
    
    param(   
                
        [Parameter()]
        [string[]]$OrganizationalUnit = @("*"),
        
        [Parameter()]
        [switch]$ExactMatch = $false,

        [Parameter()]
        [string[]]$ExcludeUser = @(),

        [Parameter()]
        [ValidateSet("Enabled","Disabled")]
        [String[]]$AccountStatus = @("Enabled")
    )

    $Accounts = @()

    IF ($OrganizationalUnit -eq $null) { $OrganizationalUnit = @("*")}

    FOREACH ($Status in $AccountStatus) {
        IF ($Status -eq "Enabled") { $Check = $true }
        IF ($Status -eq "Disabled") { $Check = $false }
        FOREACH ($OU in $OrganizationalUnit) {
            IF ($ExactMatch -eq $true -and $OU.SubString(0,3) -ne "OU=") { $OU = "OU=" + $OU }
            IF ($ExactMatch -eq $true -and $OU.SubString($OU.Length-1,1) -ne ",") { $OU += "," }
            IF (($DCCheck = $OU.Split(','))[$DCCheck.Count-2] -like "*DC=*") { $OU = $OU.Substring(0,$OU.Length-1) }           
            $OUString = "*" + $OU + "*"
            $Accounts += Get-ADUser -Filter * | Where { $_.Enabled -eq $Check } | Where { $_.DistinguishedName -like "$OUString" }
        }
    }
    $ExcludeSkip = $false
    $Results = @()
    FOREACH ($Entry in $Accounts) {
        FOREACH ($User in $ExcludeUser) { IF($Entry.SamAccountName -eq $User -or $Entry.Name -eq $User) { $ExcludeSkip = $true } }
        IF ($ExcludeSkip -eq $true) { $ExcludeSkip = $false; continue }
        $OUResult = ""
        $Properties = Get-ADUser -Identity $Entry.DistinguishedName -Properties *
        $OUPath = $Entry.DistinguishedName.Split(",")
        $Count = 1
        FOREACH ($Item in $OUPath) {
            IF ($Count -ne 1) { $OUResult += $Item + "," }
            $Count++
        }
        $OUResult = $OUResult.Substring(0,$OUResult.Length-1)
        $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
            OrganizationalUnit = $OUResult
            Enabled = $Entry.Enabled 
            #GivenName = $Entry.GivenName
            #Surname = $Entry.Surname
            Name = $Entry.Name
            #ObjectClass = $Entry.ObjectClass
            #ObjectGUID = $Entry.ObjectGUID
            SAMAccountName = $Entry.SamAccountName
            #SID = $Entry.SID
            #UserPrincipalName = $Entry.UserPrincipalName
            #BadLogonCount = $Properties.BadLogonCount
            Created = $Properties.Created
            #EmailAddress = $Properties.EmailAddress
            LastLogonDate = $Properties.LastLogonDate
            #Manager = $Properties.Manager
            PasswordLastSet = $Properties.PasswordLastSet
            #PasswordExpired = $Properties.PasswordExpired
            #PasswordNeverExpires = $Properties.PasswordNeverExpires
            #ScriptPath = $Properties.ScriptPath
          
        }
    }

    return $Results
}
Function Report-SMBShareDataTemp {
    $Results = @()
    
    ### GET SMB SHARES
    $SMBShares = Get-WMIObject -Class Win32_Share
    $ServerMeasureSum = 0
    $ServerMeasureCount = 0
    FOREACH ($SMBShare in $SMBShares) {
        
        ### SKIP THESE SHARES
        IF ($SMBShare.Name -eq "ADMIN$") { continue }
        IF ($SMBShare.Name -eq "IPC$") { continue }
        IF ($SMBShare.Name -eq "print$") { continue }
        IF ($SMBShare.Name -eq "SYSVOL") { continue }
        IF ($SMBShare.Name -eq "NETLOGON") { continue }
        IF ($SMBShare.Name -eq "Cache$") { continue }
        IF ($SMBShare.Name.Length -le 2) { continue }
        IF ($SMBShare.Name -eq "CertEnroll") { continue }
        IF ($SMBShare.Name -eq "print$") { continue }
        IF ($SMBShare.Name -eq "") { continue }
        IF ($SMBShare.Path -like "*Localspl*") { continue }

        ### GET ROOT SHARE FOLDERS
        $RootShareFolders = Get-ChildItem -Path $SMBShare.Path -Directory
        $TotalMeasureSum = 0
        $TotalMeasureCount = 0
        FOREACH ($RootShareFolder in $RootShareFolders) {
            $Measure = Get-ChildItem -Path $RootShareFolder.FullName -Recurse -Force | Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue

            $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                ComputerName = $env:COMPUTERNAME 
                ShareName = $SMBShare.Name
                SharePath = $SMBShare.Path
                FolderName = $RootShareFolder.Name
                FolderPath = $RootShareFolder.FullName
                FileCount = $Measure.Count
                TotalSizeMB = [math]::round($Measure.Sum / 1MB,2)
                TotalSizeGB = [math]::round($Measure.Sum / 1GB,2)
            }
            $TotalMeasureSum += $Measure.Sum
            $TotalMeasureCount += $Measure.Count
            $ServerMeasureSum += $Measure.Sum
            $ServerMeasureCount += $Measure.Count
        }
        $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
            ComputerName = $env:COMPUTERNAME 
            ShareName = $SMBShare.Name
            SharePath = $SMBShare.Path
            FolderName = "Share Total"
            FolderPath = "N/A"
            FileCount = $TotalMeasureCount
            TotalSizeMB = [math]::round($TotalMeasureSum / 1MB,2)
            TotalSizeGB = [math]::round($TotalMeasureSum / 1GB,2)
        }
    }

    $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
        ComputerName = $env:COMPUTERNAME 
        ShareName = "Server Total"
        SharePath = "N/A"
        FolderName = "N/A"
        FolderPath = "N/A"
        FileCount = $ServerMeasureCount
        TotalSizeMB = [math]::round($ServerMeasureSum / 1MB,2)
        TotalSizeGB = [math]::round($ServerMeasureSum / 1GB,2)
    }

    ### OUTPUT RESULTS
    $Now = Get-Date
    MKDir "C:\IntegrisPowerShell\Report-SMBShareData\Results\" -ErrorAction SilentlyContinue | Out-Null
    [string]$ExportPath = "C:\IntegrisPowerShell\Report-SMBShareData\Results\"
    $FileName = "SMB Share Data Report - "
    $FileName += $Now.ToString("yyy_MM_dd h_mm_s")
    $FileName += ".csv"
    $ExportPath += $FileName
    $Results | Select-Object ComputerName, ShareName, SharePath, FolderName, FolderPath, FileCount, TotalSizeMB, TotalSizeGB | Export-CSV -Path $ExportPath

    ### RETURN RESULTS
    Return $Results | Select-Object ComputerName, ShareName, SharePath, FolderName, FolderPath, FileCount, TotalSizeMB, TotalSizeGB
}
Function Report-SharePointPreMigationCheck {
    
    param(
        [Parameter(Mandatory,ParameterSetName = 'Path')]
        [string[]]$Path = @(),

        [Parameter(Mandatory,ParameterSetName = 'AllShares')]
        [switch]$AllShares = $false
    )

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }
    
    ### START
    $Now = Get-Date
    MKDir "C:\IntegrisPowerShell\Report-SharePointPreMigationCheck\Temp\" -ErrorAction SilentlyContinue | Out-Null
    [string]$TempPath = "C:\IntegrisPowerShell\Report-SharePointPreMigationCheck\Temp\"
    $TempPath += $Now.ToString("yyy_MM_dd h_mm_s")
    $TempPath += "\"
    MKDir $TempPath -ErrorAction SilentlyContinue | Out-Null

    IF ($AllShares -eq $true) {  
        $SMBShares = Get-WMIObject -Class Win32_Share

        FOREACH ($SMBShare in $SMBShares) {

            ### SKIP THESE SHARES
            IF ($SMBShare.Name -eq "ADMIN$") { continue }
            IF ($SMBShare.Name -eq "IPC$") { continue }
            IF ($SMBShare.Name -eq "print$") { continue }
            IF ($SMBShare.Name -eq "SYSVOL") { continue }
            IF ($SMBShare.Name -eq "NETLOGON") { continue }
            IF ($SMBShare.Name -eq "Cache$") { continue }
            IF ($SMBShare.Name.Length -le 2) { continue }
            IF ($SMBShare.Name -eq "CertEnroll") { continue }
            IF ($SMBShare.Name -eq "print$") { continue }
            IF ($SMBShare.Path -like "*LocalsplOnly*") { continue }
            IF ($SMBShare.Name -eq "") { continue }
            
            $Path += $SMBShare.Path
        }
    }
    
    $Results = @()
    
    $Files = @()
    
    $Count = 0
    ### COLLECT FILE DATA
    FOREACH ($Item in $Path) {
        $Folders = Get-ChildItem -Path $Item -Directory -Force | Select FullName     
        FOREACH ($Folder in $Folders) {
            $SavePath = $TempPath + "SharePoint Pre-Migration Temp "
            $SavePath += $Count.ToString().PadLeft(4,'0')
            $SavePath += ".csv"
            Get-ChildItem -Path $Folder.FullName -Recurse -Force | Select Name, FullName | Export-CSV -Path $SavePath -Delimiter ","
            $Count++
        }
    }
    TRY { $EncryptedFiles = cipher /u /n /h } CATCH { }

    $ExportFiles = Get-ChildItem -Path $TempPath 

    $SearchFiles = New-Object PSObject
    ### PROCESS DATA
    FOREACH ($CSV in $ExportFiles) {
        $SearchFiles = Import-CSV -Path $CSV.FullName | ForEach-Object {
            [PSCustomObject]@{
                'Name' = $_.Name
                'FullName' = $_.FullName
            }
        }
        FOREACH ($File in $SearchFiles) {
            TRY {
                IF ($File.FullName.Length -gt 200) {                
                    $IssueDetails = $File.FullName.Length.ToString()
                    $IssueDetails += " Characters" 
                    $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                        ComputerName = $env:COMPUTERNAME
                        FilePath = $File.FullName
                        IssueFound = "File Path Too Long"
                        IssueDetails = $IssueDetails
                    }
                }
            }
            CATCH { }
             
                TRY {    
                IF ($File.Name.Substring(0,1) -eq " ") { 
                    $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                        ComputerName = $env:COMPUTERNAME
                        FilePath = $File.FullName
                        IssueFound = "Invalid File Name"
                        IssueDetails = "File Name Begins With a Space"
                    }     
                }
            }
            CATCH { }

            TRY {
                IF ($File.Name.Substring(($File.Name.Length-5),1) -eq ".") {
                    IF ($File.Name.Substring(($File.Name.Length-6),1) -eq " ") { 
                        $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                            ComputerName = $env:COMPUTERNAME
                            FilePath = $File.FullName
                            IssueFound = "Invalid File Name"
                            IssueDetails = "File Name Ends With a Space"
                        }
                    }  
                }
            }
            CATCH { }
        
            TRY {
                IF ($File.Name.Substring(($File.Name.Length-4),1) -eq ".") {
                    IF ($File.Name.Substring(($File.Name.Length-5),1) -eq " ") { 
                        $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                            ComputerName = $env:COMPUTERNAME
                            FilePath = $File.FullName
                            IssueFound = "Invalid File Name"
                            IssueDetails = "File Name Ends With a Space"
                        }
                    }  
                }
            }
            CATCH { }

            TRY {
                IF ($File.Name.Substring(($File.Name.Length-3),1) -eq ".") {
                    IF ($File.Name.Substring(($File.Name.Length-4),1) -eq " ") { 
                        $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                            ComputerName = $env:COMPUTERNAME
                            FilePath = $File.FullName
                            IssueFound = "Invalid File Name"
                            IssueDetails = "File Name Ends With a Space"
                        }
                    }  
                }
            }
            CATCH { }

                TRY {
                IF ($EncryptedFiles -contains $File.FullName) {
                    $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                        ComputerName = $env:COMPUTERNAME
                        FilePath = $File.FullName
                        IssueFound = "Encrypted File"
                        IssueDetails = "File is Encrypted with EFS Encryption"
                    }
                }
            }
            CATCH { }                     
        }
    }

    ### OUTPUT RESULTS
    $Now = Get-Date
    MKDir "C:\IntegrisPowerShell\Report-SharePointPreMigationCheck\Results\" -ErrorAction SilentlyContinue | Out-Null
    [string]$ExportPath = "C:\IntegrisPowerShell\Report-SharePointPreMigationCheck\Results\"
    $FileName = "SharePoint Pre-Migration Report - "
    $FileName += $Now.ToString("yyy_MM_dd h_mm_s")
    $FileName += ".csv"
    $ExportPath += $FileName
    $Results | Select-Object IssueFound, IssueDetails, ComputerName, FilePath | Export-CSV -Path $ExportPath

    ### RETURN RESULTS
    Return $Results | Select-Object IssueFound, IssueDetails, ComputerName, FilePath
}

Export-ModuleMember -Function Report-PCPerformance
Export-ModuleMember -Function Report-PCSummary
Export-ModuleMember -Function Report-NTFSPermissions
Export-ModuleMember -Function Report-ADGroupMembership
Export-ModuleMember -Function Report-ADUser
Export-ModuleMember -Function Report-SMBShareData
Export-ModuleMember -Function Report-SharePointPreMigationCheck

### ### ==============================================================================================
### ### CHECK FUNCTIONS
### ### ==============================================================================================

Function Check-All {

    <#
    .SYNOPSIS
        Automatically checks for issues and highlights potential issues.
 
    .DESCRIPTION
 
        PARAMETERS
            N/A
 
        NOTES
            Results highlighted in yellow are possibly a problem.
         
            Results highlighted in red are very likely a problem.
 
        TIPS
            This is a work in progress. Report issues to David.
 
    .EXAMPLE
        Check-All
 
    .LINK
        https://bjn.itglue.com/1902395/docs/14305861
    #>



$LeftPadding = 30
Write-Host ""
Write-Host " Operating System Information"
Write-Host "============================================================"
$OSName = Check-OSName
Write-Host ("Operating System: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $OSName[0] -ForegroundColor $OSName[1]

$OSBuildVersion = Check-OSBuildVersion
Write-Host ("OS Build Version: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $OSBuildVersion[0] -ForegroundColor $OSBuildVersion[1]

$OSDriveFreeSpace = Check-OSDriveFreeSpace
Write-Host ("OS Free Drive Space: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $OSDriveFreeSpace[0] -ForegroundColor $OSDriveFreeSpace[1] -NoNewline
Write-Host ""
Write-Host ""
Write-Host " Hardware Information"
Write-Host "============================================================"
$OSDriveType = Check-OSDriveType
Write-Host ("OS Drive Type: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $OSDriveType[0] -ForegroundColor $OSDriveType[1] -NoNewline
Write-Host ""
Write-Host ""
Write-Host " Network Information"
Write-Host "============================================================"
$WiredNetwork = Check-WiredNetwork
Write-Host ("Wired Connection: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $WiredNetwork[0] -ForegroundColor $WiredNetwork[1]

$WiredLinkSpeed = Check-WiredLinkSpeed
Write-Host ("Wired Link Speed: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $WiredLinkSpeed[0] -ForegroundColor $WiredLinkSpeed[1]

$WiFiAdapterSSID = Check-WiFiAdapterSSID
Write-Host ("WiFi SSID: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $WiFiAdapterSSID[0] -ForegroundColor $WiFiAdapterSSID[1]

$WiFiProtocol = Check-WiFiProtocol
Write-Host ("WiFi Protocol: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $WiFiProtocol[0] -ForegroundColor $WiFiProtocol[1]

$WiFiSignalStrength = Check-WiFiSignalStrength
Write-Host ("WiFi Signal Strength: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $WiFiSignalStrength[0] -ForegroundColor $WiFiSignalStrength[1]

$WiFiLinkSpeed = Check-WiFiLinkSpeed
Write-Host ("WiFi Link Speed: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $WiFiLinkSpeed[0] -ForegroundColor $WiFiLinkSpeed[1]

$NetworkProfile = Check-NetworkProfile
Write-Host ("Network Profile: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $NetworkProfile[0] -ForegroundColor $NetworkProfile[1]

Write-Host ""
Write-Host " DNS Information"
Write-Host "============================================================"
$DNSSuffixes = Check-DNSSuffixes
Write-Host ("DNS Suffixes: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $DNSSuffixes[0] -ForegroundColor $DNSSuffixes[1]

$DNSResolutionInternal = Check-DNSResolutionInternal
Write-Host ("Internal DNS Test: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $DNSResolutionInternal[0] -ForegroundColor $DNSResolutionInternal[1]

$DNSResolutionExternal = Check-DNSResolutionExternal
Write-Host ("External DNS Test: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $DNSResolutionExternal[0] -ForegroundColor $DNSResolutionExternal[1]

$DNSType = Check-DNSType
Write-Host ("DNS Assignment Type: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $DNSType[0] -ForegroundColor $DNSType[1]
Write-Host ""
Write-Host " Security Information"
Write-Host "============================================================"
$LastSecurityUpdateDate = Check-LastSecurityUpdateDate
Write-Host ("Last Security Update: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $LastSecurityUpdateDate[0] -ForegroundColor $LastSecurityUpdateDate[1]
$CheckCryptoProtocols = Check-CryptoProtocols
Write-Host ("Enabled Crypto Protocols: ").PadLeft($LeftPadding,' ') -NoNewline
Write-Host $CheckCryptoProtocols[0] -ForegroundColor $CheckCryptoProtocols[1]
Write-Host ""

}

Export-ModuleMember -Function Check-All

### ### ==============================================================================================
### ### CHECK HELPER FUNCTIONS
### ### ==============================================================================================

Function Check-WiredNetwork {
    $ReturnVar = @("", "")
    $var1 = $null
    $var1 = Get-NetAdapter | Where-Object { $_.Status -eq "Up" -and $_.Name -ne "Wi-Fi" -and $_.InterfaceDescription -ne "Hyper-V Virtual Ethernet Adapter" -and $_.InterfaceDescription -notlike "*SonicWall*" }
    IF ($var1 -eq $null) { $ReturnVar[0] = "No Wired Connection"; $ReturnVar[1] = "White"; return $ReturnVar }
    IF ($var1 -ne $null) { $ReturnVar[0] = "Wired Connection"; $ReturnVar[1] = "White"; return $ReturnVar }
}
Function Check-WiredLinkSpeed {
    $ReturnVar = @("", "")
    $var1 = $null
    $var1 = Get-NetAdapter | Where-Object { $_.Status -eq "Up" -and $_.Name -ne "Wi-Fi" -and $_.InterfaceDescription -ne "Hyper-V Virtual Ethernet Adapter" -and $_.InterfaceDescription -notlike "*SonicWall*"  }
    IF ($var1 -eq $null) { $ReturnVar[0] = "No Wired Connection"; $ReturnVar[1] = "White"; return $ReturnVar }
    IF ($var1.LinkSpeed -like "*Mbps*") { $ReturnVar[0] = $var1.LinkSpeed; $ReturnVar[1] = "Yellow"; return $ReturnVar }
    ELSE { $ReturnVar[0] = $var1.LinkSpeed; $ReturnVar[1] = "White"; return $ReturnVar }
}
Function Check-WiFiAdapterSSID {
    $ReturnVar = @("", "")
    $var1 = netsh wlan show interfaces | select-string -Pattern "[\s]SSID"
    IF ($var1 -eq $null) {
        $var2 = Get-NetAdapter -Name "Wi-Fi" -ErrorAction SilentlyContinue
        IF ($var2 -eq $null) { 
            $ReturnVar[0] = "No WiFi Interface Found"
            $ReturnVar[1] = "White"
            return $ReturnVar  
        }
        IF ($var2.status -ne "Up") { 
            $ReturnVar[0] = "WiFi Interface Not Connected"
            $ReturnVar[1] = "Yellow"
            return $ReturnVar 
        }
    }
    $var1 = $var1.tostring().replace(" SSID : ","")
    IF ($var1 -like "*guest*") { 
        $ReturnVar[0] = $var1
        $ReturnVar[1] = "Yellow"
        return $ReturnVar
    }
    
    $ReturnVar[0] = $var1
    $ReturnVar[1] = "White"
    return $ReturnVar
} 
Function Check-WiFiProtocol {
    $ReturnVar = @("", "")
    $var1 = netsh wlan show interfaces | select-string -Pattern "[\s]SSID"
    IF ($var1 -eq $null) {
        $var2 = Get-NetAdapter -Name "Wi-Fi" -ErrorAction SilentlyContinue
        IF ($var2 -eq $null) { 
            $ReturnVar[0] = "No WiFi Interface Found"
            $ReturnVar[1] = "White"
            return $ReturnVar  
        }
        IF ($var2.status -ne "Up") { 
            $ReturnVar[0] = "WiFi Interface Not Connected"
            $ReturnVar[1] = "Yellow"
            return $ReturnVar 
        }
    }
    $var1 = netsh wlan show interfaces | select-string -Pattern "[\s]Radio Type"
    $var1 = $var1.tostring().replace(" Radio type : ","")
    IF($var1 -eq "802.11ac") { return "802.11ac", "White" }
    IF($var1 -eq "802.11ax") { return "802.11ax", "White" }
    return $var1, "Yellow"
}
Function Check-WiFiSignalStrength {
    $ReturnVar = @("", "")
    $var1 = netsh wlan show interfaces | select-string -Pattern "[\s]SSID"
    IF ($var1 -eq $null) {
        $var2 = Get-NetAdapter -Name "Wi-Fi" -ErrorAction SilentlyContinue
        IF ($var2 -eq $null) { 
            $ReturnVar[0] = "No WiFi Interface Found"
            $ReturnVar[1] = "White"
            return $ReturnVar  
        }
        IF ($var2.status -ne "Up") { 
            $ReturnVar[0] = "WiFi Interface Not Connected"
            $ReturnVar[1] = "Yellow"
            return $ReturnVar 
        }
    }
    $var1 = netsh wlan show interfaces | select-string -Pattern "[\s]Signal"
    $var1 = $var1.tostring().replace(" Signal : ","")
    return $var1, "White"
}
Function Check-WiFiLinkSpeed {
    $ReturnVar = @("", "")
    $var1 = netsh wlan show interfaces | select-string -Pattern "[\s]SSID"
    IF ($var1 -eq $null) {
        $var2 = Get-NetAdapter -Name "Wi-Fi" -ErrorAction SilentlyContinue
        IF ($var2 -eq $null) { 
            $ReturnVar[0] = "No WiFi Interface Found"
            $ReturnVar[1] = "White"
            return $ReturnVar  
        }
        IF ($var2.status -ne "Up") { 
            $ReturnVar[0] = "WiFi Interface Not Connected"
            $ReturnVar[1] = "Yellow"
            return $ReturnVar 
        }
    }
    $var1 = netsh wlan show interfaces | select-string -Pattern "[\s]Receive"
    $var1 = $var1.tostring().replace(" Receive rate (Mbps) : ","")
    $var2 = netsh wlan show interfaces | select-string -Pattern "[\s]Transmit"
    $var2 = $var1.tostring().replace(" Transmit rate (Mbps) : ","")
    
    return ($var1 + "/" + $var2 + " Mbps").ToString(), "White"
}
Function Check-DNSSuffixes {
    $ReturnVar = @("", "")
    $var3 = $null
    $var1 = Get-DNSClient | select Suffix,InterfaceIndex
    FOREACH ($var2 in $var1) {
        IF ($var2.suffix -eq "") { continue }
        IF ($var2.suffix -like "*reddog.microsoft*") { continue }
        $var4 = Get-NetAdapter -ifindex $var2.InterfaceIndex
        IF ($var4.status -ne "Up") { continue }
        $var3 += $var2.suffix
        $var3 += ", "
    }
    IF ($var3.Length -lt 3) { $ReturnVar[0] = "No DNS Suffixes Found"; $ReturnVar[1] = "Yellow"; return $ReturnVar }
    ELSE { $var3 = $var3.ToString().Substring(0,$var3.Length-2) }
    $ReturnVar[0] = $var3
    IF ($var3 -like "*lan*") { $ReturnVar[1] = "Yellow" }
    ELSE { $ReturnVar[1] = "White" }
    return $ReturnVar
}
Function Check-DNSResolutionExternal {
    $ReturnVar = @("", "")
    $var1 = 0
    $var2 = 0
    FOR ($i = 0; $i -lt 10; $i++) {
        $var3 = Resolve-DnsName Google.com -QuickTimeout -ErrorAction SilentlyContinue
        IF ($var3 -eq $null) { $var2++ }
        ELSE { $var1++ }
        IF ( $var2 -eq 3) { $ReturnVar[0] = "Definite External DNS Issue Found"; $ReturnVar[1] = "Red"; return $ReturnVar }
    }
    IF ( $var2 -eq 2) { $ReturnVar[0] = "Probable External DNS Issue Found"; $ReturnVar[1] = "Red"; return $ReturnVar }
    IF ( $var2 -eq 1) { $ReturnVar[0] = "Possible External DNS Issue Found"; $ReturnVar[1] = "Yellow"; return $ReturnVar }
    IF ( $var2 -eq 0) { $ReturnVar[0] = "No External DNS Issues Found"; $ReturnVar[1] = "White"; return $ReturnVar }
}
Function Check-DNSResolutionInternal {
    $ReturnVar = @("", "")
    $var4 = $null
    $var1 = Get-DnsClient | select Suffix,InterfaceIndex
    FOREACH ($var2 in $var1) {
        IF ($var2.suffix -eq "") { continue }
        IF ($var2.suffix -like "*reddog.microsoft*") { continue }
        IF ($var2.suffix -eq "lan") { continue }
        $var3 = Get-NetAdapter -ifindex $var2.InterfaceIndex
        IF ($var3.status -eq "Up") { $var4 = ping $var2.suffix } ELSE { continue } 
        IF ($var4 -like "*Ping request could not find host*") { 
            $ReturnVar[0] = "Internal DNS Failure for " + $var2.suffix
            $ReturnVar[1] = "Red"
            return $ReturnVar
        }
     }
     $ReturnVar[0] = "No Internal DNS Issues Found"
     $ReturnVar[1] = "White"
     return $ReturnVar
}
Function Check-DNSType {
    $ReturnVar = @("", "")
    $Adapters = Get-NetAdapter
    FOREACH ($Adapter in $Adapters) {
        IF ($Adapter.Status -eq "Up") {
            IF ($Adapter.InterfaceDescription -like "*Sonicwall*") { continue }
            IF ($Adapter.InterfaceDescription -like "*AppGate*") { continue }
            IF ($Adapter.InterfaceDescription -like "*VPN*") { continue }
            $DeviceName = $Adapter.DeviceName
            $DeviceName = $DeviceName.Replace("\Device\","")

            $KeyName = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\" + $DeviceName

            $Value = "NULL"
            $Value = Get-ItemPropertyValue -Path $KeyName -Name NameServer
            IF ( $Value -like "*.*" ) { 
                $ReturnVar[0] = "Static DNS on Interface " + $Adapter.InterfaceDescription
                $ReturnVar[1] = "Yellow"
                return $ReturnVar 
            }
            ELSE { Continue }
        }
    }
    $ReturnVar[0] = "Dynamic"
    $ReturnVar[1] = "White"
    return $ReturnVar 
}
Function Check-OSName {
    $ReturnVar = @("", "")
    $var1 = (Get-WmiObject -class Win32_OperatingSystem).Caption
    IF ($var1 -like "*Home*") { $ReturnVar[0] = $var1; $ReturnVar[1] = "Red"; return $ReturnVar }
    IF ($var1 -like "*XP*") { $ReturnVar[0] = $var1; $ReturnVar[1] = "Yellow"; return $ReturnVar }
    IF ($var1 -like "*Vista*") { $ReturnVar[0] = $var1; $ReturnVar[1] = "Yellow"; return $ReturnVar }
    IF ($var1 -like "*7*") { $ReturnVar[0] = $var1; $ReturnVar[1] = "Yellow"; return $ReturnVar }
    $ReturnVar[0] = $var1
    $ReturnVar[1] = "White"
    return $ReturnVar
}
Function Check-OSBuildVersion {
    $ReturnVar = @("", "")
    $var1 = [System.Environment]::OSVersion.Version.Build
    IF($var1 -eq "19045") { $ReturnVar[0] = $var1; $ReturnVar[1] = "White"; return $ReturnVar }
    IF($var1 -eq "22000") { $ReturnVar[0] = $var1; $ReturnVar[1] = "White"; return $ReturnVar }
    IF($var1 -eq "22621") { $ReturnVar[0] = $var1; $ReturnVar[1] = "White"; return $ReturnVar }
    $ReturnVar[0] = $var1; $ReturnVar[1] = "Yellow"; return $ReturnVar
}
Function Check-NetworkProfile {
    $ReturnVar = @("", "")
    $var1 = Get-NetConnectionProfile
    IF($var1.NetworkCategory -like "*Public*") { $ReturnVar[0] = $var1.NetworkCategory; $ReturnVar[1] = "Yellow"; return $ReturnVar }
    IF($var1.NetworkCategory -like "*Private*") { $ReturnVar[0] = $var1.NetworkCategory; $ReturnVar[1] = "Yellow"; return $ReturnVar }
    ELSE { $ReturnVar[0] = $var1.NetworkCategory; $ReturnVar[1] = "White"; return $ReturnVar }
}
Function Check-OSDriveFreeSpace {
    $ReturnVar = @("", "")
    $Partition = Get-Partition | Where IsBoot -EQ True

    $OSDriveLetter = $Partition.DriveLetter
    $OSDriveLetter += ":"

    $Drive = Get-CimInstance -ClassName CIM_LogicalDisk | Where DeviceID -EQ $OSDriveLetter

    [int]$FreeGBs = $Drive.FreeSpace / 1000000000

    IF ($FreeGBs -LT 25 ) { $ReturnVar[0] = $FreeGBs.ToString() + " GBs"; $ReturnVar[1] = "Yellow"; return $ReturnVar }
    IF ($FreeGBs -LT 10 ) { $ReturnVar[0] = $FreeGBs.ToString() + " GBs"; $ReturnVar[1] = "Red"; return $ReturnVar }
    ELSE { $ReturnVar[0] = $FreeGBs.ToString() + " GBs"; $ReturnVar[1] = "White"; return $ReturnVar }
}
Function Check-OSDriveType {
    $ReturnVar = @("", "")
    $DriveLetter = $env:windir
    $DriveLetter = $DriveLetter.Substring(0,1)
    $Partition = Get-Partition -DriveLetter $DriveLetter

    $DiskNumber = Get-Partition -DriveLetter $DriveLetter
    $DiskNumber = $DiskNumber.DiskNumber

    $PhysicalDisk = Get-PhysicalDisk -DeviceNumber $DiskNumber
    IF ($PhysicalDisk.MediaType -like "*SSD*") {
        $ReturnVar[0] = $PhysicalDisk.BusType + " " + $PhysicalDisk.MediaType
        $ReturnVar[1] = "White"
    }
    ELSE {
        $ReturnVar[0] = $PhysicalDisk.BusType + " " + $PhysicalDisk.MediaType
        $ReturnVar[1] = "Yellow"
    }
    return $ReturnVar
}
Function Check-LastSecurityUpdateDate {
   $ReturnVar = @("", "")
    
   $LastSecurityUpdateDate = Get-HotFix -Description "Security Update" | Sort-Object -Property InstalledOn -Descending | Select-Object -First 1
   $ReturnVar[0] = $LastSecurityUpdateDate.InstalledOn.ToShortDateString()
   
   $Now = Get-Date
   $ElapsedTime = $Now - $LastSecurityUpdateDate.InstalledOn
   IF($ElapsedTime.TotalDays -gt 90) { $ReturnVar[1] = "Red" }
   ELSEIF($ElapsedTime.TotalDays -gt 35) { $ReturnVar[1] = "Yellow" }
   ELSE { $ReturnVar[1] = "White" }
   
   return $ReturnVar
}
Function Check-CryptoProtocols {
    $ReturnVar = @("", "")

    $Protocols = Get-CryptoProtocols

    $ReturnVar[0] = $Protocols
    IF ($Protocols -like "*SSL*" -or $Protocols -like "*TLS 1.0*") { $ReturnVar[1] = "Yellow" }
    ELSE { $ReturnVar[1] = "White" }

    return $ReturnVar
}

### ### ==============================================================================================
### ### CLEANUP FUNCTIONS
### ### ==============================================================================================

Function DiskCleanup-All {

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }
    $StartSpace = Get-OSDiskFreeSpace 
    $StartSpaceRound = [math]::round($StartSpace,2)
    Write-Host ""
    Write-Host "Starting Space:" $StartSpaceRound "GBs of Space"
    Write-Host "========================================================="
    DiskCleanup-DiskCleanup
    DiskCleanup-WindowsAppClutter
    DiskCleanup-NiniteTempData
    DiskCleanup-DellData
    DiskCleanup-ClearOldDownloads
    DiskCleanup-ClearRecycleBin
    DiskCleanup-ShadowStorage 
    DiskCleanup-Hibernation 
    DiskCleanup-MailboxCaching 
    DiskCleanup-WindowsInstallerFolder 
    DiskCleanup-OfficeUpdateFolder 
    DiskCleanup-PageFile
    Write-Host "========================================================="
    $EndSpace = Get-OSDiskFreeSpace
    $EndSpaceRound = [math]::round($EndSpace,2)
    $FreedSpace = [Math]::Abs($StartSpace - $EndSpace)
    $FreedSpaceRound = [math]::round($FreedSpace,2)
    Write-Host "Ending Space:" $EndSpaceRound "GBs of Space"
    Write-Host "Total Freed Space:" $FreedSpaceRound "GBs of Space"
    Write-Host ""
    Return
}
Function DiskCleanup-DiskCleanup {

    param(
        [int]$FreeSpaceThreshold = 75
    )

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }

    function Set-RegistryValueForAllUsers { 
    <#
    .SYNOPSIS
        This function uses Active Setup to create a "seeder" key which creates or modifies a user-based registry value
        for all users on a computer. If the key path doesn't exist to the value, it will automatically create the key and add the value.
    .EXAMPLE
        PS> Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'Setting'; 'Type' = 'String'; 'Value' = 'someval'; 'Path' = 'SOFTWARE\Microsoft\Windows\Something'}
      
        This example would modify the string registry value 'Type' in the path 'SOFTWARE\Microsoft\Windows\Something' to 'someval'
        for every user registry hive.
    .PARAMETER RegistryInstance
         A hash table containing key names of 'Name' designating the registry value name, 'Type' to designate the type
        of registry value which can be 'String,Binary,Dword,ExpandString or MultiString', 'Value' which is the value itself of the
        registry value and 'Path' designating the parent registry key the registry value is in.
    #>
 
    [CmdletBinding()] 
    param ( 
        [Parameter(Mandatory=$true)] 
        [hashtable[]]$RegistryInstance 
    ) 
    try { 
        New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null 
         
        ## Change the registry values for the currently logged on user. Each logged on user SID is under HKEY_USERS
        $LoggedOnSids = (Get-ChildItem HKU: | where { $_.Name -match 'S-\d-\d+-(\d+-){1,14}\d+$' }).PSChildName 
        Write-Host "Found $($LoggedOnSids.Count) logged on user SIDs" 
        foreach ($sid in $LoggedOnSids) { 
            Write-Host -Message "Loading the user registry hive for the logged on SID $sid" 
            foreach ($instance in $RegistryInstance) { 
                ## Create the key path if it doesn't exist
                New-Item -ErrorAction SilentlyContinue -Path ("HKU:\$sid\$($instance.Path)" | Split-Path -Parent) -Name ("HKU:\$sid\$($instance.Path)" | Split-Path -Leaf) | Out-Null
                ## Create (or modify) the value specified in the param
                New-Item -Path "HKU:\$sid\SOFTWARE\Policies\Microsoft\Office"
                New-Item -Path "HKU:\$sid\SOFTWARE\Policies\Microsoft\Office\16.0"
                New-Item -Path "HKU:\$sid\SOFTWARE\Policies\Microsoft\Office\16.0\Outlook"
                New-Item -Path "HKU:\$sid\SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode"

                Set-ItemProperty -Path "HKU:\$sid\$($instance.Path)" -Name $instance.Name -Value $instance.Value -Type $instance.Type -Force 
            } 
        } 
         
        ## Create the Active Setup registry key so that the reg add cmd will get ran for each user
        ## logging into the machine.
        ## http://www.itninja.com/blog/view/an-active-setup-primer
        Write-Host "Setting Active Setup registry value to apply to all other users" 
        foreach ($instance in $RegistryInstance) { 
            ## Generate a unique value (usually a GUID) to use for Active Setup
            $Guid = [guid]::NewGuid().Guid 
            $ActiveSetupRegParentPath = 'HKLM:\Software\Microsoft\Active Setup\Installed Components' 
            ## Create the GUID registry key under the Active Setup key
            New-Item -Path $ActiveSetupRegParentPath -Name $Guid | Out-Null 
            $ActiveSetupRegPath = "HKLM:\Software\Microsoft\Active Setup\Installed Components\$Guid" 
            Write-Host "Using registry path '$ActiveSetupRegPath'" 
             
            ## Convert the registry value type to one that reg.exe can understand. This will be the
            ## type of value that's created for the value we want to set for all users
            switch ($instance.Type) { 
                'String' { 
                    $RegValueType = 'REG_SZ' 
                } 
                'Dword' { 
                    $RegValueType = 'REG_DWORD' 
                } 
                'Binary' { 
                    $RegValueType = 'REG_BINARY' 
                } 
                'ExpandString' { 
                    $RegValueType = 'REG_EXPAND_SZ' 
                } 
                'MultiString' { 
                    $RegValueType = 'REG_MULTI_SZ' 
                } 
                default { 
                    throw "Registry type '$($instance.Type)' not recognized" 
                } 
            } 
             
            ## Build the registry value to use for Active Setup which is the command to create the registry value in all user hives
            $ActiveSetupValue = "reg add `"{0}`" /v {1} /t {2} /d {3} /f" -f "HKCU\$($instance.Path)", $instance.Name, $RegValueType, $instance.Value 
            Write-Host -Message "Active setup value is '$ActiveSetupValue'" 
            ## Create the necessary Active Setup registry values
            Set-ItemProperty -Path $ActiveSetupRegPath -Name '(Default)' -Value 'Active Setup Test' 
            Set-ItemProperty -Path $ActiveSetupRegPath -Name 'Version' -Value '1' 
            Set-ItemProperty -Path $ActiveSetupRegPath -Name 'StubPath' -Value $ActiveSetupValue
        } 
    } catch { 
        Write-Warning -Message $_.Exception.Message 
    } 
}

    $GBsFreeSpace = Get-OSDiskFreeSpace
    IF ($GBsFreeSpace -lt $FreeSpaceThreshold) {
        $StartSpace = Get-OSDiskFreeSpace
        $results = Get-ChildItem HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches
        $Reset=$False
        FOREACH($result in $results) {
            IF($Reset -eq $False) {
                #this is what is returned in $result.name:
                #HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\<some name>
                #change HKEY_LOCAL_MACHINE to HKLM:
            
                IF($Downloads -eq $False -and $result.name -eq "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\DownloadsFolder") { }
                ELSE {
                    $tmp = 'HKLM:' + $result.Name.Substring( 18 )
                    $tmp2 = $result.Name.SubString( $result.Name.LastIndexOf( '\' ) + 1 )
                    #Write-Host "Setting $tmp2 to 2"
                    $null = New-ItemProperty -Path $tmp -Name 'StateFlags0001' -Value 2 -PropertyType DWORD -Force -EA 0 | Out-Null
                
                    If(!$?) { Write-Warning "`tUnable to set $tmp2" }
                }
            }
            ELSEIF ($Reset -eq $True) {
                $tmp = 'HKLM:' + $result.Name.Substring( 18 )
                $tmp2 = $result.Name.SubString( $result.Name.LastIndexOf( '\' ) + 1 )
                #Write-Host "Resetting $tmp2 to 0"
                $null = New-ItemProperty -Path $tmp -Name 'StateFlags0001' -Value 0 -PropertyType DWORD -Force -EA 0 | Out-Null
            
                IF(!$?) { Write-Warning "`tUnable to set $tmp2" }
            }
        }
        cleanmgr /sagerun:1 | Out-Null
        
        Write-Host "Disk Cleanup Started... Waiting 3 Minutes"
        Start-Sleep -Seconds 180
        $EndSpace = Get-OSDiskFreeSpace
        $FreedSpace = [Math]::Abs($StartSpace - $EndSpace)
        Return "Disk Cleanup Freed " + [math]::round($FreedSpace,2) + " GBs of Space"
    }
    ELSE { Return "Disk Cleanup Skipped" } 
}
Function DiskCleanup-WindowsAppClutter {
    
    param(
        [int]$FreeSpaceThreshold = 60
    )
    $GBsFreeSpace = Get-OSDiskFreeSpace

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }
    
    IF ($GBsFreeSpace -lt $FreeSpaceThreshold) {        
        $StartSpace = Get-OSDiskFreeSpace
        $Now = Get-Date
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*xbox*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*disney*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*netflix*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*warships*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*yourphone*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*candy*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*office.desktop*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*skype*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*zune*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*bing*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*print3d*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*mixedreality*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*feedback*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*solitaire*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*office.onenote*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*minecraft*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*marchofempires*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*bubblewitch*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*cookings*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*candy*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*whiteboard*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*HiddenCity*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*MysteryofShadow*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*Mahjong*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*Facebook*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*King.com*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*Bingo*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*KeeperS*" } -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
            
                      
        $Items = Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*HPPrinterControl*" } -ErrorAction SilentlyContinue
        IF ($Items.Count -gt 1) { $Items | Sort CreationTime -Descending | Select -Last ($Items.Count-1) | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }

        $Items = Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*Microsoft.Todos*" } -ErrorAction SilentlyContinue
        IF ($Items.Count -gt 1) { $Items | Sort CreationTime -Descending | Select -Last ($Items.Count-1) | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }

        $Items = Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*Microsoft.Windows.Photos*" } -ErrorAction SilentlyContinue
        IF ($Items.Count -gt 1) { $Items | Sort CreationTime -Descending | Select -Last ($Items.Count-1) | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }

        $Items = Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*microsoft.windowscommunicationsapps*" } -ErrorAction SilentlyContinue
        IF ($Items.Count -gt 1) { $Items | Sort CreationTime -Descending | Select -Last ($Items.Count-1) | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }

        $Items = Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*HPPrinterControl*" } -ErrorAction SilentlyContinue
        IF ($Items.Count -gt 1) { $Items | Sort CreationTime -Descending | Select -Last ($Items.Count-1) | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }

        $Items = Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*AppUp.IntelManagement*" } -ErrorAction SilentlyContinue
        IF ($Items.Count -gt 1) { $Items | Sort CreationTime -Descending | Select -Last ($Items.Count-1) | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }

        $Items = Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*Microsoft.MicrosoftEdge.Stable*" } -ErrorAction SilentlyContinue
        IF ($Items.Count -gt 1) { $Items | Sort CreationTime -Descending | Select -Last ($Items.Count-1) | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }

        $Items = Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*HPPrinterControl*" } -ErrorAction SilentlyContinue
        IF ($Items.Count -gt 1) { $Items | Sort CreationTime -Descending | Select -Last ($Items.Count-1) | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }

        $Items = Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*Microsoft.NET.Native.Framework*" } -ErrorAction SilentlyContinue
        IF ($Items.Count -gt 1) { $Items | Sort CreationTime -Descending | Select -Last ($Items.Count-1) | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }

        $Items = Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*Microsoft.NET.Native.Runtime*" } -ErrorAction SilentlyContinue
        IF ($Items.Count -gt 1) { $Items | Sort CreationTime -Descending | Select -Last ($Items.Count-1) | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }

        $Items = Get-ChildItem -Path "C:\Program Files\WindowsApps" -Directory -ErrorAction SilentlyContinue | where { $_.Name -like "*Microsoft.UI.Xaml*" } -ErrorAction SilentlyContinue
        IF ($Items.Count -gt 1) { $Items | Sort CreationTime -Descending | Select -Last ($Items.Count-1) | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue }
                
        $EndSpace = Get-OSDiskFreeSpace
        $FreedSpace = [Math]::Abs($StartSpace - $EndSpace)
        Return "Windows Apps Cleanup Freed " + [math]::round($FreedSpace,2) + " GBs of Space"
    }
    ELSE { Return "Windows Apps Cleanup Skipped" }
 }
Function DiskCleanup-NiniteTempData {

    param(
        [int]$FreeSpaceThreshold = 50
    )
    $GBsFreeSpace  = Get-OSDiskFreeSpace

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }

    IF ($GBsFreeSpace -lt $FreeSpaceThreshold) {
        $Now = Get-Date
        $Time = $Now.AddDays(-360)
        $StartSpace = Get-OSDiskFreeSpace
        Get-ChildItem -Path "C:\Windows\LTSvc\packages" -Directory | where { $_.Name -like "*DiskSpeedTest*" } | Remove-Item -Recurse -Force
        Get-ChildItem -Path "C:\Windows\LTSvc\packages" -Directory | where { $_.Name -like "*MITPSpeedTest*" } | Remove-Item -Recurse -Force
        Get-ChildItem -Path "C:\Windows\LTSvc\packages\MP\Ninite" -Directory | where { $_.Name -like "*NiniteDownloads*" } | Remove-Item -Recurse -Force
        Get-Item -Path "C:\BJN" -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        $EndSpace = Get-OSDiskFreeSpace
        $FreedSpace = [Math]::Abs($StartSpace - $EndSpace)
        Return "Ninite Temp Data Cleanup Freed " + [math]::round($FreedSpace,2) + " GBs of Space"
    }
    ELSE { Return "Ninite Temp Data Cleanup Skipped" }
 }
Function DiskCleanup-DellData {

    param(
        [int]$FreeSpaceThreshold = 50
    )
    $GBsFreeSpace  = Get-OSDiskFreeSpace

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }

    IF ($GBsFreeSpace -lt $FreeSpaceThreshold) {
        $Now = Get-Date
        $Time = $Now.AddDays(-360)
        $StartSpace = Get-OSDiskFreeSpace
        Get-Item -Path "C:\Windows\Internet Logs"  -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Get-Item -Path "C:\ProgramData\Dell\SARemediation"  -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        $EndSpace = Get-OSDiskFreeSpace
        $FreedSpace = [Math]::Abs($StartSpace - $EndSpace)
        Return "Dell Data Cleanup Freed " + [math]::round($FreedSpace,2) + " GBs of Space"
    }
    ELSE { Return "Dell Data Cleanup Skipped" }
 }
Function DiskCleanup-ClearOldDownloads {

    param(
        [int]$FreeSpaceThreshold = 40,
        [int]$DaysOldThreshold = 60
    )
    $GBsFreeSpace  = Get-OSDiskFreeSpace

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }

    IF ($GBsFreeSpace -lt $FreeSpaceThreshold) {
        $Now = Get-Date
        $Time = $Now.AddDays(-$DaysOldThreshold)
        $StartSpace = Get-OSDiskFreeSpace
        $Users = Get-ChildItem -Path "C:\Users\" -Directory 
        FOREACH ($User in $Users) {    
            $Dir = "C:\Users\"
            $Dir += $User.Name
            $Dir += "\Downloads"
            $Items = Get-ChildItem -Path $Dir -Recurse -ErrorAction SilentlyContinue | Where { $_.LastWriteTime -lt $Time } | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        }
        $EndSpace = Get-OSDiskFreeSpace
        $FreedSpace = [Math]::Abs($StartSpace - $EndSpace)
        Return "Downloads Cleanup Freed " + [math]::round($FreedSpace,2) + " GBs of Space"
    }
    ELSE { Return "Downloads Cleanup Skipped" }
 }
Function DiskCleanup-ClearRecycleBin {

    param(
        [int]$FreeSpaceThreshold = 40
    )

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }

    $GBsFreeSpace  = Get-OSDiskFreeSpace

    IF ($GBsFreeSpace -lt $FreeSpaceThreshold) {
        $Now = Get-Date
        $Time = $Now.AddDays(-$DaysOldThreshold)
        $StartSpace = Get-OSDiskFreeSpace
        

        Clear-RecycleBin -DriveLetter C: -Force -ErrorAction SilentlyContinue
        Get-ChildItem -Path 'C:\$Recycle.Bin' -Force | Remove-Item -Recurse -ErrorAction SilentlyContinue


        $EndSpace = Get-OSDiskFreeSpace
        $FreedSpace = [Math]::Abs($StartSpace - $EndSpace)
        Return "Recycle Bin Cleanup Freed " + [math]::round($FreedSpace,2) + " GBs of Space"
    }
    ELSE { Return "Recycle Bin Cleanup Skipped" }
 }
Function DiskCleanup-ShadowStorage {
    param(
        [int]$FreeSpaceThreshold = 50
    )
    $GBsFreeSpace = Get-OSDiskFreeSpace

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }
    
    IF ($GBsFreeSpace -lt $FreeSpaceThreshold) {
        $StartSpace = Get-OSDiskFreeSpace
        vssadmin resize shadowstorage /For=C: /On=C: /MaxSize=10% | Out-Null
        $EndSpace = Get-OSDiskFreeSpace
        $FreedSpace = [Math]::Abs($StartSpace - $EndSpace)
        Return "Shadow Storage Resize Freed " + [math]::round($FreedSpace,2) + " GBs of Space"
    }
    ELSE { Return "Shadow Storage Resize Skipped" }
}
Function DiskCleanup-Hibernation {
    param(
        [int]$FreeSpaceThreshold = 30
    )

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }
    
    $GBsFreeSpace = Get-OSDiskFreeSpace
    IF ($GBsFreeSpace -lt $FreeSpaceThreshold) {
        $StartSpace = Get-OSDiskFreeSpace
        PowerCFG /H Off
        $EndSpace = Get-OSDiskFreeSpace
        $FreedSpace = [Math]::Abs($StartSpace - $EndSpace)
        Return "Disable Hibernation Freed " + [math]::round($FreedSpace,2) + " GBs of Space"
    }
    ELSE { Return "Disable Hibernation Skipped" }

}
Function DiskCleanup-MailboxCaching {

    param(
        [int]$FreeSpaceThreshold = 25,
        [int]$UserThreshold = 2
    )

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }

    function Set-RegistryValueForAllUsers { 
    <#
    .SYNOPSIS
        This function uses Active Setup to create a "seeder" key which creates or modifies a user-based registry value
        for all users on a computer. If the key path doesn't exist to the value, it will automatically create the key and add the value.
    .EXAMPLE
        PS> Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'Setting'; 'Type' = 'String'; 'Value' = 'someval'; 'Path' = 'SOFTWARE\Microsoft\Windows\Something'}
      
        This example would modify the string registry value 'Type' in the path 'SOFTWARE\Microsoft\Windows\Something' to 'someval'
        for every user registry hive.
    .PARAMETER RegistryInstance
         A hash table containing key names of 'Name' designating the registry value name, 'Type' to designate the type
        of registry value which can be 'String,Binary,Dword,ExpandString or MultiString', 'Value' which is the value itself of the
        registry value and 'Path' designating the parent registry key the registry value is in.
    #>
 
    [CmdletBinding()] 
    param ( 
        [Parameter(Mandatory=$true)] 
        [hashtable[]]$RegistryInstance 
    ) 
    try { 
        New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null 
         
        ## Change the registry values for the currently logged on user. Each logged on user SID is under HKEY_USERS
        $LoggedOnSids = (Get-ChildItem HKU: | where { $_.Name -match 'S-\d-\d+-(\d+-){1,14}\d+$' }).PSChildName 
        Write-Host "Found $($LoggedOnSids.Count) logged on user SIDs" 
        foreach ($sid in $LoggedOnSids) { 
            Write-Host -Message "Loading the user registry hive for the logged on SID $sid" 
            foreach ($instance in $RegistryInstance) { 
                ## Create the key path if it doesn't exist
                New-Item -ErrorAction SilentlyContinue -Path ("HKU:\$sid\$($instance.Path)" | Split-Path -Parent) -Name ("HKU:\$sid\$($instance.Path)" | Split-Path -Leaf) | Out-Null
                ## Create (or modify) the value specified in the param
                New-Item -Path "HKU:\$sid\SOFTWARE\Policies\Microsoft\Office" | Out-Null
                New-Item -Path "HKU:\$sid\SOFTWARE\Policies\Microsoft\Office\16.0" | Out-Null
                New-Item -Path "HKU:\$sid\SOFTWARE\Policies\Microsoft\Office\16.0\Outlook" | Out-Null
                New-Item -Path "HKU:\$sid\SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode" | Out-Null

                Set-ItemProperty -Path "HKU:\$sid\$($instance.Path)" -Name $instance.Name -Value $instance.Value -Type $instance.Type -Force 
            } 
        } 
         
        ## Create the Active Setup registry key so that the reg add cmd will get ran for each user
        ## logging into the machine.
        ## http://www.itninja.com/blog/view/an-active-setup-primer
        Write-Host "Setting Active Setup registry value to apply to all other users" 
        foreach ($instance in $RegistryInstance) { 
            ## Generate a unique value (usually a GUID) to use for Active Setup
            $Guid = [guid]::NewGuid().Guid 
            $ActiveSetupRegParentPath = 'HKLM:\Software\Microsoft\Active Setup\Installed Components' 
            ## Create the GUID registry key under the Active Setup key
            New-Item -Path $ActiveSetupRegParentPath -Name $Guid | Out-Null 
            $ActiveSetupRegPath = "HKLM:\Software\Microsoft\Active Setup\Installed Components\$Guid" 
            Write-Host "Using registry path '$ActiveSetupRegPath'" 
             
            ## Convert the registry value type to one that reg.exe can understand. This will be the
            ## type of value that's created for the value we want to set for all users
            switch ($instance.Type) { 
                'String' { 
                    $RegValueType = 'REG_SZ' 
                } 
                'Dword' { 
                    $RegValueType = 'REG_DWORD' 
                } 
                'Binary' { 
                    $RegValueType = 'REG_BINARY' 
                } 
                'ExpandString' { 
                    $RegValueType = 'REG_EXPAND_SZ' 
                } 
                'MultiString' { 
                    $RegValueType = 'REG_MULTI_SZ' 
                } 
                default { 
                    throw "Registry type '$($instance.Type)' not recognized" 
                } 
            } 
             
            ## Build the registry value to use for Active Setup which is the command to create the registry value in all user hives
            $ActiveSetupValue = "reg add `"{0}`" /v {1} /t {2} /d {3} /f" -f "HKCU\$($instance.Path)", $instance.Name, $RegValueType, $instance.Value 
            Write-Host -Message "Active setup value is '$ActiveSetupValue'" 
            ## Create the necessary Active Setup registry values
            Set-ItemProperty -Path $ActiveSetupRegPath -Name '(Default)' -Value 'Active Setup Test' 
            Set-ItemProperty -Path $ActiveSetupRegPath -Name 'Version' -Value '1' 
            Set-ItemProperty -Path $ActiveSetupRegPath -Name 'StubPath' -Value $ActiveSetupValue
        } 
    } catch { 
        Write-Warning -Message $_.Exception.Message 
    } 
}
    
    $GBsFreeSpace = Get-OSDiskFreeSpace
    IF ($GBsFreeSpace -lt $FreeSpaceThreshold) {
        $StartSpace = Get-OSDiskFreeSpace
        $Profiles = Get-ChildItem -Path "C:\Users" -Directory | where { $_.Name -notlike "*admin*" -and $_.Name -notlike "*cyberhawk*" -and $_.Name -notlike "*defaultapppool*" -and $_.Name -notlike "*labtechservice*" -and $_.Name -notlike "*public*" }
        $Count = 0
        FOREACH ($Profile in $Profiles) {
            $SearchPath = $Profile.FullName + "\AppData\Local\Microsoft\Outlook"
            $OSTs = Get-ChildItem -Path $SearchPath -ErrorAction SilentlyContinue | where { $_.Name -like "*.ost*" } 
            FOREACH ($OST in $OSTs) {
                $Count++
                break
            }
        }
        IF ($Count -gt $UserThreshold-1) {
            While (Get-Process "Outlook" -ErrorAction SilentlyContinue) {
                taskkill /IM “outlook.exe” /f | Out-Null
                Start-Sleep -Seconds 5
            }
            Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'CacheOthersMail'; 'Type' = 'DWORD'; 'Value' = '0'; 'Path' = 'SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'} -ErrorAction SilentlyContinue
            Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'Enable'; 'Type' = 'DWORD'; 'Value' = '0'; 'Path' = 'SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'} -ErrorAction SilentlyContinue
            Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'DownloadSharedFolders'; 'Type' = 'DWORD'; 'Value' = '0'; 'Path' = 'SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Cached Mode'} -ErrorAction SilentlyContinue
            Set-RegistryValueForAllUsers -RegistryInstance @{'Name' = 'NoOST'; 'Type' = 'DWORD'; 'Value' = '2'; 'Path' = 'SOFTWARE\Microsoft\Office\16.0\Outlook\OST'} -ErrorAction SilentlyContinue
            FOREACH ($Profile in $Profiles) {
                $SearchPath = $Profile.FullName + "\AppData\Local\Microsoft\Outlook"
                $OSTs = Get-ChildItem -Path $SearchPath -ErrorAction SilentlyContinue | where { $_.Name -like "*.ost*" } 
                FOREACH ($OST in $OSTs) {
                    Remove-Item $OST.FullName
                }
            }
        }
        ELSE { Return "Outlook Mailbox Cache Cleanup Skipped" }
        $EndSpace = Get-OSDiskFreeSpace
        $FreedSpace = [Math]::Abs($StartSpace - $EndSpace)
        Return "Outlook Mailbox Cache Cleanup Freed " + [math]::round($FreedSpace,2) + " GBs of Space"
    }
    ELSE { Return "Outlook Mailbox Cache Cleanup Skipped" }
}
Function DiskCleanup-WindowsInstallerFolder {

    param(
        [int]$FreeSpaceThreshold = 30,
        [int]$DaysOldThreshold = 180
    )

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }

    $GBsFreeSpace = Get-OSDiskFreeSpace
    IF ($GBsFreeSpace -lt $FreeSpaceThreshold) {
        $StartSpace = Get-OSDiskFreeSpace
        $Time = Get-Date
        $Time = $Time.AddDays(-$DaysOldThreshold)
        Get-ChildItem -Path "C:\Windows\Installer" | where { $_.LastWriteTime -lt $Time } | Remove-Item -Recurse -Force
        $EndSpace = Get-OSDiskFreeSpace
        $FreedSpace = [Math]::Abs($StartSpace - $EndSpace)
        Return "Windows Installer Folder Cleanup Freed " + [math]::round($FreedSpace,2) + " GBs of Space"
    }
    ELSE { Return "Windows Installer Folder Cleanup Skipped" }
}
Function DiskCleanup-OfficeUpdateFolder {

    param(
        [int]$FreeSpaceThreshold = 35
    )

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }

    $GBsFreeSpace = Get-OSDiskFreeSpace
    IF ($GBsFreeSpace -lt $FreeSpaceThreshold) {
        $StartSpace = Get-OSDiskFreeSpace
        $Time = Get-Date
        $Time = $Time.AddDays(-14)
        Get-ChildItem -Path "C:\Program Files\Microsoft Office\Updates\Download\PackageFiles" | where { $_.LastWriteTime -lt $Time } | Remove-Item -Recurse -Force
        $EndSpace = Get-OSDiskFreeSpace
        $FreedSpace = [Math]::Abs($StartSpace - $EndSpace)
        Return "Office Update Folder Cleanup Freed " + [math]::round($FreedSpace,2) + " GBs of Space"
    }
    ELSE { Return "Office Update Folder Cleanup Skipped" }
}
Function DiskCleanup-PageFile {
    param(
        [int]$FreeSpaceThreshold = 30,
        [int64]$InitialSize = 2GB,
        [int64]$MaximumSize = 4GB
    )

    IF (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] “Administrator”)) {
         Write-Warning “You do not have Administrator rights to run this script.`nNo changes were made. Please re-run this command as an Administrator.”
         Return
    }
    
    $GBsFreeSpace = Get-OSDiskFreeSpace
    IF ($GBsFreeSpace -lt $FreeSpaceThreshold) {
        $pagefile = Get-CimInstance -ClassName Win32_ComputerSystem
        $pagefile.AutomaticManagedPagefile = $false
        Set-CimInstance -InputObject $pagefile

        $pagefileset = Get-CimInstance -ClassName Win32_PageFileSetting | Where-Object {$_.name -eq "$ENV:SystemDrive\pagefile.sys"}
        $pagefileset.InitialSize = $InitialSize / 1KB / 1KB
        $pagefileset.MaximumSize = $MaximumSize / 1KB / 1KB
        Set-CimInstance -InputObject $pagefileset -ErrorAction SilentlyContinue
        
        Return "Page File Cleanup Performed" 
    }
    ELSE { Return "Page File Cleanup Skipped" }
}
Function Get-OSDiskFreeSpace {
    $Partition = Get-Partition | Where IsBoot -EQ True
    $OSDriveLetter = $Partition.DriveLetter
    $OSDriveLetter += ":"
    $Drive = Get-CimInstance -ClassName CIM_LogicalDisk | Where DeviceID -EQ $OSDriveLetter
    $GBsFreeSpace = $Drive.FreeSpace / 1024 / 1024 / 1024
    Return $GBsFreeSpace
}








    










Clear-Host

# ========================================================
# ============== Determine Manufacturer ==================
# ========================================================

$Manufacturer = Get-CimInstance -ClassName Win32_ComputerSystem | Select Manufacturer
$Manufacturer = $Manufacturer.Manufacturer

# ========================================================
# ==================== HP Commands =======================
# ========================================================

#Show BIOS Config and Options
#Get-WmiObject -Namespace root/hp/instrumentedBIOS -Class hp_biosEnumeration |Format-Table Name,Value -AutoSize

Function Get-HPBIOSSettings
{ 
    $Script:Get_BIOS_Settings = Get-WmiObject -Namespace root/hp/instrumentedBIOS -Class hp_biosEnumeration -ErrorAction SilentlyContinue |  % { New-Object psobject -Property @{    
    Setting = $_."Name"
    Value = $_."currentvalue"
    Available_Values = $_."possiblevalues"
    }}  | select-object Setting, Value, possiblevalues
    $Get_BIOS_Settings
} 

# ========================================================
# =================== Dell Commands ======================
# ========================================================

Function IntGet-DellBIOSSettings
{
    IF ((Get-PackageProvider -Name NuGet) -eq $null) { Install-PackageProvider NuGet -Force }
    IF ((Get-PackageSource -Name PSGallery) -eq $null) { Register-PackageSource -Name PSGallery -ProviderName PowerShellGet -ErrorAction SilentlyContinue }
    IF ((Get-Module -Name DellBIOSProvider) -eq $null) { Install-Module DellBIOSProvider -Force -RequiredVersion 2.6.0 -AllowClobber -ErrorAction SilentlyContinue }
    IF ((Get-Module -Name SMBIOS) -eq $null) { Install-Module -Name SMBIOS -Force -AllowClobber -ErrorAction SilentlyContinue }
    Start-Sleep -Seconds 3
    Import-Module DellBIOSProvider -ErrorAction SilentlyContinue
    Import-Module SMBIOS -ErrorAction SilentlyContinue

    $WarningPreference='silentlycontinue'
    If (Get-Module -ListAvailable -Name DellBIOSProvider) {} 
    Else {
        Install-Module -Name DellBIOSProvider -Force -Confirm
    }

    Get-Command -Module DellBIOSProvider | out-null
    $Script:Get_BIOS_Settings = get-childitem -path DellSmbios:\ | select-object category | 
    
    FOREACH {
        Get-Childitem -path @("DellSmbios:\" + $_.Category)  | select-object attribute, currentvalue 
    } 
    $Script:Get_BIOS_Settings = $Get_BIOS_Settings |  % { New-Object psobject -Property @{
    Setting = $_."attribute"
    Value = $_."currentvalue"
    }}  | select-object Setting, Value 
    $Get_BIOS_Settings
}  

# ========================================================
# ================== Lenovo Commands =====================
# ========================================================

Function Get-LenovoBIOSSettings
{
    (Get-WmiObject -Class Lenovo_BiosSetting -Namespace root\wmi).CurrentSetting | Where-Object {$_ -ne ""} | Sort-Object
}

# ========================================================
# ================= Config Automation ====================
# ========================================================
Function Stuff {
IF ($Manufacturer -like "*Hewlett*") { 
    Write-Host "Started Configuring HP Bios Settings"

    $BIOSSettings = Get-WmiObject -Namespace root/hp/instrumentedBIOS -Class HP_BIOSSettingInterface

    $BIOSSettings.SetBIOSSetting("AMT","Enable","")
    $BIOSSettings.SetBIOSSetting("Virtualization Technology (VTx)","Enable","")
    $BIOSSettings.SetBIOSSetting("Virtualization Technology Directed I/O (VTd)","Enable","")
    $BIOSSettings.SetBIOSSetting("Intel(R) VT-d","Enable","")
    $BIOSSettings.SetBIOSSetting("TPM State","Enable","")
    $BIOSSettings.SetBIOSSetting("TPM Device","Available","")
    $BIOSSettings.SetBIOSSetting("After Power Loss","On","")
    $BIOSSettings.SetBIOSSetting("S5 Wake on LAN","Enable","")

    Write-Host "Finished Configuring HP Bios Settings"
}

IF ($Manufacturer -like "*Dell*") { 
    Write-Host "Started Configuring Dell Bios Settings"

    $Policy = Get-ExecutionPolicy
    Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force
    Install-PackageProvider NuGet -Force
    Install-Module -Name DellBIOSProvider -Force
    Install-Module -Name SMBIOS -Force
    Import-Module DellBIOSProvider
    Set-ExecutionPolicy -ExecutionPolicy $Policy -Force

    Set-Item -Path DellSmbios:\VirtualizationSupport\Virtualization -Value "Enabled"
    Set-Item -Path DellSmbios:\VirtualizationSupport\VtForDirectIo -Value "Enabled"
    Set-Item -Path DellSmbios:\PowerManagement\BlockSleep -Value "Disabled"
    Set-Item -Path DellSmbios:\PowerManagement\WakeOnLan -Value "LanOnly"
    Set-Item -Path DellSmbios:\PowerManagement\AcPwrRcvry "On"
    Set-Item -Path DellSmbios:\PowerManagement\WakeOnAC "Enabled"
    Set-Item -Path DellSmbios:\SystemConfiguration\UefiNwStack -Value "Enabled"
    Set-Item -Path DellSmbios:\TPMSecurity\TpmSecurity "Enabled"
    Set-Item -Path DellSmbios:\TPMSecurity\TpmActivation "Enabled"
    Set-Item -Path DellSmbios:\SystemConfiguration\SmartErrors "Enabled"

    Write-Host "Finished Configuring Dell Bios Settings"
}

IF ($Manufacturer -like "*Lenovo*") { 
    Write-Host "Started Configuring Lenovo Bios Settings"

    (Get-WmiObject -Class Lenovo_SetBiosSetting -Namespace root\wmi -ErrorAction Stop).SetBiosSetting("Wake On LAN,Automatic")
    (Get-WmiObject -Class Lenovo_SetBiosSetting -Namespace root\wmi -ErrorAction Stop).SetBiosSetting("VT-d,Enabled")
    (Get-WmiObject -Class Lenovo_SetBiosSetting -Namespace root\wmi -ErrorAction Stop).SetBiosSetting("Intel(R) Virtualization Technology,Enabled")
    (Get-WmiObject -Class Lenovo_SetBiosSetting -Namespace root\wmi -ErrorAction Stop).SetBiosSetting("Intel(R) SpeedStep(TM) Technology,Enabled")
    (Get-WmiObject -Class Lenovo_SetBiosSetting -Namespace root\wmi -ErrorAction Stop).SetBiosSetting("After Power Loss,Power On,")

    (Get-WmiObject -Class Lenovo_SaveBiosSettings -Namespace root\wmi -ErrorAction Stop).SaveBiosSettings()

    Write-Host "Finished Configuring Lenovo Bios Settings"
}

IF ($Manufacturer -notlike "*Lenovo*" -and $Manufacturer -notlike "*Dell*" -and $Manufacturer -notlike "*Hewlett*") { 
    Write-Host "Script Does Not Support BIOS Configuration For This Computer"
}
}