<# windows-localhost-discovery-v0.11.ps1
Purpose: scan the local or remote Windows machine for general system resources, security settings, and users information
Copyright? GPLv3 by KimConnect.com
#>

$remoteComputer="REMOTESHERVER009"
$adminCredential=Get-Credential

<#
################################## Excuting Program as an Administrator ####################################
# Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
 
# Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
 
# Check to see if we are currently running "as Administrator"
if ($myWindowsPrincipal.IsInRole($adminRole))
   {
   # We are running "as Administrator" - so change the title and background color to indicate this
   $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
   $Host.UI.RawUI.BackgroundColor = "Black"
   clear-host
   }
else
   {
   # We are not running "as Administrator" - so relaunch as administrator
   
   # Create a new process object that starts PowerShell
   $newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
   
   # Specify the current script path and name as a parameter
   $newProcess.Arguments = $myInvocation.MyCommand.Definition;
   
   # Indicate that the process should be elevated
   $newProcess.Verb = "runas";
   
   # Start the new process
   [System.Diagnostics.Process]::Start($newProcess);
   
   # Exit from the current, unelevated, process
   exit
   }
 
Write-Host -NoNewLine "Running as Administrator..."
################################## Excuting Program as an Administrator ####################################
#>


function checkWindows{  
    param(
        [string]$computerName=$env:computername,
        $adminCredential
    )
    
    $domain=(net config workstation) -match 'Workstation domain\s+\S+$' -replace '.+?(\S+)$','$1';
    $defaultDomainAdmin="$domain\Administrator"    

    Function checkServiceAccount{
        param(
            [string]$searchForAccount=$defaultDomainAdmin
        )     
        
        $servicesMatch="";
        $taskFound = "";
        $scheduledTaskMatches=@();
                   
        # Use the legacy schtasks command from localhost to query local machine and format an output int CSV format              
        $tasksAsCSV = schtasks.exe /query /V /FO CSV

        # Process the CSV result into PowerShell. Filter entries that are not labeled as "TaskName" and by "Run as User" field matching the target account
        $tasksFound = $tasksAsCSV | ConvertFrom-Csv | Where { $_.TaskName -ne "TaskName" -and $_."Run As User" -eq $searchForAccount}
        if ($tasksFound){
            $matches+="Scheduled Tasks 'Run-As' account $searchForAccount found:`r`n---------------------------------------------------";
            $scheduledTaskMatches=foreach ($task in $tasksFound){"`r`nTaskName: $($task.TaskName)`r`n---Executable: $($task.'Task To Run')`r`n---Next Run: $($task.'Next Run Time')"}	
		$matches+=$scheduledTaskMatches
            }	
	
        #$servicesMatch=(Get-Wmiobject win32_service | where-object{$_.startname -like $searchForAccount}|select @{name="ServiceName";expression={$_.name}}).ServiceName|out-string
	$servicesMatch=Get-Wmiobject win32_service|?{$_.StartName -like $searchForAccount}|select Name,DisplayName,StartName,StartMode,Status|ft -AutoSize|Out-String

        if($servicesMatch){
            $matches+="Services 'Run-As' account $searchForAccount found:`n";
            $matches+="$servicesMatch";
            }
        return $matches;
    }

    function getHyperVHostname{
        param([string]$guestVMName=$env:computername)
        $hive = [Microsoft.Win32.RegistryHive]::LocalMachine;
        $keyPath = 'SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters';
        $value = 'HostName';
        $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($hive, $guestVMName);
        $key = $reg.OpenSubKey($keyPath);
        return $key.GetValue($value) ;
    }

    # Function obtained from 
    # Author: AJIT GUPTA
    function Get-ActivationStatus {
    [CmdletBinding()]
        param(
            [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
            [string]$DNSHostName = $Env:COMPUTERNAME
        )
        process {
            try {
                $wpa = Get-WmiObject SoftwareLicensingProduct -ComputerName $DNSHostName `
                -Filter "ApplicationID = '55c92734-d682-4d71-983e-d6ec3f16059f'" `
                -Property LicenseStatus -ErrorAction Stop
            } catch {
                $status = New-Object ComponentModel.Win32Exception ($_.Exception.ErrorCode)
                $wpa = $null    
            }
            $out = New-Object psobject -Property @{
                ComputerName = $DNSHostName;
                Status = [string]::Empty;
            }
            if ($wpa) {
                :outer foreach($item in $wpa) {
                    switch ($item.LicenseStatus) {
                        0 {$out.Status = "Unlicensed"}
                        1 {$out.Status = "Licensed"; break outer}
                        2 {$out.Status = "Out-Of-Box Grace Period"; break outer}
                        3 {$out.Status = "Out-Of-Tolerance Grace Period"; break outer}
                        4 {$out.Status = "Non-Genuine Grace Period"; break outer}
                        5 {$out.Status = "Notification"; break outer}
                        6 {$out.Status = "Extended Grace"; break outer}
                        default {$out.Status = "Unknown value"}
                    }
                }
            } else {$out.Status = $status.Message}
            return $out.Status
        }
    }

    function retryScriptBlock {
            [CmdletBinding()]
            Param(
                [Parameter(Position=0, Mandatory=$true)]
                [scriptblock]$ScriptBlock,

                [Parameter(Position=1, Mandatory=$false)]
                [int]$Maximum = 5
            )

            Begin {
                $cnt = 0
            }

            Process {
                do {
                    $cnt++
                    try {
                        $ScriptBlock.Invoke()
                        return
                    } catch {
                        Write-Error $_.Exception.InnerException.Message -ErrorAction Continue
                    }
                } while ($cnt -lt $Maximum)

                # Throw an error after $Maximum unsuccessful invocations. Doesn't need
                # a condition, since the function returns upon successful invocation.
                throw 'Execution failed.'
            }
        }

    function getWinDefenderStatus{
        param(
            $remoteSherver="localhost"
        )    
        
        $regexGetVersion='(<[^>]+>|[:\s]+|Version)';
        $regexGetReleaseDate='(<[^>]+>|^\s|\s+$|Released:)';
        $latestRelease=retryScriptBlock -scriptBlock {(Invoke-WebRequest –Uri "https://www.microsoft.com/en-us/wdsi/definitions" -Method Get -UseBasicParsing).tostring() -split "[`r`n]"};
        $latestVersion=($latestRelease | select-string "Version:") -replace $regexGetVersion;
        $latestReleaseDate=($latestRelease | select-string "Released:") -replace $regexGetReleaseDate -replace "  ";
        $result="";
            try{                   
                $mpStatus=Get-MpComputerStatus
                $actualVersion=$mpStatus.AntivirusSignatureVersion -replace $regexGetVersion
                $lastUpdated=$mpStatus.AntispywareSignatureLastUpdated                
                $releaseDateLocalTime=[System.TimeZoneInfo]::ConvertTimeFromUtc($latestReleaseDate,[System.TimeZoneInfo]::FindSystemTimeZoneById((Get-WmiObject win32_timezone).StandardName))
                $timeDifference = New-TimeSpan -Start $lastUpdated -End $latestReleaseDate
                $daysDifference=$timeDifference.Days
                
                "It has been $daysDifference day(s) between Last Update: $lastUpdated and New Release: $latestReleaseDate";
                if ($actualVersion -ne $latestVersion){
                    $result+="Malware Antivirus Signature version $actualVersion on this system does not match the Latest version of $latestVersion";
                    #Update-MPSignature;
                    }
                else{
                    $result+= "Excellent! Malware Antivirus Definition $actualVersion on this computer matches the Microsoft release.";                    
                }       
            }
            catch{
                $result+="Windows Defender is NOT enabled on this system.";
            }      
        return $result;
    }

    function checkRDP{
        $rdpAuth=(Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -Filter "TerminalName='RDP-tcp'").UserAuthenticationRequired
        $encryptionLevel=(Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -Filter "TerminalName='RDP-tcp'").MinEncryptionLevel
        switch ($encryptionLevel){
            1 {$compliant="Low";}
            2 {$compliant="Client Compatible";}
            3 {$compliant="High";}
            4 {$compliant="FIPS Compliant";}
        }
        if($rdpAuth){return "RDP Network Authentication Requirement: passed!`nRDP Encryption Level: $compliant";}else{return "RDP Network Authentication Requirement: Fail";}
    }
    
    function checkSpectreVulnerability{
        $regexOctets="([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)"
	    $patchedVersion="10.0.14393.2842"
	    $actualVersion=(Get-Item C:\Windows\system32\mcupdate_genuineintel.dll | select VersionInfo).VersionInfo.ProductVersion

        $temp=$actualVersion -match $regexOctets;
        [string]$a1=$matches[1].PadLeft(3,'0');
        [string]$a2=$matches[2].PadLeft(8,'0');
        [string]$a3=$matches[3].PadLeft(8,'0');
        [string]$a4=$matches[4].PadLeft(8,'0');        
        [single]$a=$a1+$a2+$a3+$a4

        $temp=$patchedVersion -match $regexOctets;
        [string]$p1=$matches[1].PadLeft(3,'0');
        [string]$p2=$matches[2].PadLeft(8,'0');
        [string]$p3=$matches[3].PadLeft(8,'0');
        [string]$p4=$matches[4].PadLeft(8,'0');
        [single]$p=$p1+$p2+$p3+$p4

        "System version: $actualVersion VS minimum version required: $patchedVersion"

        if($a -ge $p){return "Spectre meltdown vulnerabilities: Pass";}else{return "Spectre meltdown vulnerabilities: Fail";}  
        }

    function checkOtherVulnerabilities{
        $result="";

        # Checking IE
        $ieKeys=@(
            @("CVE-2017-8529 FEATURE_ENABLE_PRINT_INFO_DISCLOSURE_FIX (32-Bit)","HKLM:SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ENABLE_PRINT_INFO_DISCLOSURE_FIX"),
            @("CVE-2017-8529 FEATURE_ENABLE_PRINT_INFO_DISCLOSURE_FIX (64-bit)","HKLM:SOFTWARE\WOW6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ENABLE_PRINT_INFO_DISCLOSURE_FIX"),
            @("MS15-124-Critical ASLR Hardening Setting for IE (32-Bit)","HKLM:SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ALLOW_USER32_EXCEPTION_HANDLER_HARDENING"),
            @("MS15-124-Critical ASLR Hardening Setting for IE (64-Bit)","HKLM:SOFTWARE\WOW6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_ALLOW_USER32_EXCEPTION_HANDLER_HARDENING")
        )    
        $result+="Internet Explorer Overall: "
        foreach ($ieKey in $ieKeys){
                try{
                    $value=(Get-ItemProperty -Path $ieKey[1] -Name "iexplore.exe" -ErrorAction SilentlyContinue).'iexplore.exe';
                }
                catch{
                    $value=0;
                    continue;
                }
                $ieResult=if($value){"Pass"}else{"Fail";}
                $ieKey[0] + ": " + $ieResult
            }
        $result+="$ieResult";
        
        # Checking Memory Management
        $memKeys=@(
            @("CVE-2017-5715 FeatureSettingsOverride","HKLM:SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management","FeatureSettingsOverride","0"),
            @("CVE-2017-5715 FeatureSettingsOverrideMask","HKLM:SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management","FeatureSettingsOverrideMask","3"),
            @("CVE-2017-5753-54 MinVmVersionForCpuBasedMitigations","HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization","MinVmVersionForCpuBasedMitigations","1.0")
        )
        $result+="`nMemory Management Registry Keys: "
        foreach ($memKey in $memKeys){
            $value=(Get-ItemProperty -Path $memKey[1] -Name $memKey[2] -ErrorAction SilentlyContinue).[string]($memKey[2])
            $memResult=if($value -eq $memKey[3]){"Pass"}else{"Fail";}
            $memKey[0]+ ": " + $memResult;
        }
        $result+="$memResult";

        # Checking Remote Code Execution
        $minVersion=14
        $vcVersions=(Get-ItemProperty Registry::HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*  -ErrorAction SilentlyContinue| where {$_.displayname -like "Microsoft Visual C++*"} | Select-Object DisplayVersion)
        foreach ($version in $vcVersions){
            if($version.DisplayVersion -ge $minVersion){
                $safeFlag=$True;
            }
        }
        if ($safeFlag){
            $result+="`nMS11-025 (MFC Remote Code Execution): Pass"
        }
        else{$result+="`nMS11-025 (MFC Remote Code Execution): Fail"}
        
        # Checking unquoted service path enumeration        
        $unquotedServicePathItems=(wmic service get name","displayname","pathname","startmode |findstr /i "auto" |findstr /i /v "c:\windows\\" |findstr /i /v "''").Trim()
        if ($unquotedServicePathItems){$result+="`nUnquoted Service Path Enumeration Vulnerabilities: Fail."}else{$result+="`nUnquoted Service Path Enumeration Vulnerabilities: Passed."}
        
        # Checking LAPS
        # (reg query HKLM\SOFTWARE\Classes /s /f Admpwd.dll)
        if((Get-ChildItem 'C:\Program Files\LAPS\CSE\Admpwd.dll' -ErrorAction SilentlyContinue) -OR (Get-ChildItem 'C:\Windows\Admpwd.dll' -ErrorAction SilentlyContinue)){$result+="`nLAPS is installed."}else{$result+="`nLAPS is not installed.";}
        
        # Checking SNMP
            try{
                $permittedManagers=Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\services\SNMP\Parameters\PermittedManagers" -ErrorAction SilentlyContinue;
                $validCommunities=Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\services\SNMP\Parameters\ValidCommunities" -ErrorAction SilentlyContinue;
            }
            finally{
            if (($permittedManagers) -and ($validCommunities)){
                $result+="`nSNMP: permittedManagers and validCommunities values are detected.";
                    }else{
                        $result+="`nSNMP: permittedManagers and validCommunities values are NOT detected.";
                        }
        }
        
        # Checking IISCrypto
        $iisServer=Get-Service -Name 'IISADMIN' -ErrorAction SilentlyContinue | Select -ExpandProperty Status
        if($iisServer){
            $result+="`nIIS is detected on this system with status $iisServer"
            $regHiveSSL30="Registry::HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server"
            $regHiveTLS10="Registry::HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server"
            $regHiveTLS11="Registry::HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" 
            $regHiveTLS12="Registry::HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server"
            $isSSL30Enabled = Get-ItemProperty -Path $regHiveSSL30 -Name "Enabled" -ErrorAction SilentlyContinue
            $isTLS10Enabled = Get-ItemProperty -Path $regHiveTLS10 -Name "Enabled" -ErrorAction SilentlyContinue
            $isTLS11Enabled = Get-ItemProperty -Path $regHiveTLS11 -Name "Enabled" -ErrorAction SilentlyContinue
            $isTLS12Enabled = Get-ItemProperty -Path $regHiveTLS12 -Name "Enabled" -ErrorAction SilentlyContinue
            If ($isSSL30Enabled) {$result+="`nSSL 3.0 is Enabled.";} ElseIf ($isSSL30Enabled -eq 0){$result+="`nSSL 3.0 is Disabled.";} else {$result+="`nSSL 3.0 SCHANNEL is not detected.";}
            If ($isTLS10Enabled) {$result+="`nTLS 1.0 is Enabled.";} ElseIf ($isTLS10Enabled -eq 0){$result+="`nTLS 1.0 is Disabled.";} else {$result+="`nTLS 1.0 SCHANNEL is not detected.";}
            If ($isTLS11Enabled) {$result+="`nTLS 1.1 is Enabled.";} ElseIf ($isTLS11Enabled -eq 0){$result+="`nTLS 1.1 is Disabled.";} else {$result+="`nTLS 1.2 SCHANNEL is not detected.";}
            If ($isTLS12Enabled) {$result+="`nTLS 1.2 is Enabled.";} ElseIf ($isTLS12Enabled -eq 0){$result+="`nTLS 1.2 is Disabled.";} else {$result+="`nTLS 1.2 SCHANNEL is not detected.";}
            #If([System.IO.File]::Exists("C:\Windows\IISCryptoCli.exe")){$result+="`nIISCryptoCli is available."}else{$result+="`nIISCryptoCli is not available at C:\Windows.";}
            if((Get-Command IISCryptoCli.exe -ErrorAction SilentlyContinue) -or (Get-Command IISCrypto.exe -ErrorAction SilentlyContinue)){$result+="`nIIS Crypto is available on this system."}else{$result+="`nIIS Crypto is not available on this system.";}
        }
        
        return $result;        
    }

    function getAntivirusName {  
        $wmiQuery = "SELECT * FROM AntiVirusProduct"                  
        $antivirus = Get-WmiObject -Namespace "root\SecurityCenter2" -Query $wmiQuery  @psboundparameters -ErrorVariable myError -ErrorAction 'SilentlyContinue'             

        if($antivirus){
            return $antivirus.displayName            
            }else{
                $alternateAntivirusQuery=WMIC /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct GET displayName /Format:List|?{$_.trim() -ne ""}|%{$_ -replace "displayName=",""}
                if ($alternateAntivirusQuery){                    
                    return $alternateAntivirusQuery
                    }else{
                        write-host "No antivirus software were detected. Hence, namespace querying errors."
                        $rawSearch=((get-wmiobject -class "Win32_Process" -namespace "root\cimv2" | where-object {$_.Name.ToLower() -match "antivirus|endpoint|protection|security|defender|msmpeng"}).Name | Out-String).Trim();
                        if($rawSearch){
                            return $rawSearch
                            }else{
                                return "No antivirus detected."
                                }
                        }
                
                } 
        }
    
    function removeBlankLines{
        param($inputObject)
        return $inputObject|Out-String|?{$_.Trim("\s") -ne ""}
    }    

    <#
    Purpose: to measure IOPS of local volumes or UNC paths
    - This function must be ran with Administrator privileges, especially when triggered for the first time on a local system
    - Two utilities will be required and installed on the system: chocolatey (DevOps Tool) and diskspd.exe (Microsoft's disk benchmark app, similar to SQLIO)
    - Call the function with a valid path to test disk speed, such as:
      getDiskSpeed C:\
      getDiskSpeed \\FILESHERVER01\TESTDIR1
      getDiskSpeed D
    #>
    function getDiskSpeed{

        param(
            [string]$driveLetter="c:",
            [int]$sampleSize=5
            )
                
        if($driveLetter.Length -eq 1){$driveLetter+=":";}
        write-host "Obtaining disk speed of $driveLetter"        

        function isPathWritable{
                param($testPath)
                # Create random test file name
                $tempFolder=$testPath+"\getDiskSpeed\"
	            $filename = "diskSpeedTest-"+[guid]::NewGuid()
	            $tempFilename = (Join-Path $tempFolder $filename)
                New-Item -ItemType Directory -Path $tempFolder -Force -EA SilentlyContinue|Out-Null
	
	            Try { 
		            # Try to add a new file
                    # New-Item -ItemType Directory -Path $tempFolder -Force -EA SilentlyContinue
		            [io.file]::OpenWrite($tempFilename).close()
		            #Write-Host -ForegroundColor Green "$testPath is writable."         
		
		            # Delete test file after done
		            # Remove-Item $tempFilename -Force -ErrorAction SilentlyContinue 
                    
                    # Set return value
                    $feasible=$true;
	                }
	            Catch {
                    # Return 'false' if there are errors
                    $feasible=$false;
	                }

                return $feasible;
                }

        # Check if input is a valid drive letter
        function validatePath{
            param([string]$path=$driveLetter)
            if (Test-Path $path -EA SilentlyContinue){    
                $regexValidDriveLetters="^[A-Za-z]\:{0,1}$"
                $validLocalPath=$path.SubString(0,2) -match $regexValidDriveLetters
                if ($validLocalPath){
                $GLOBAL:localPath=$true;
                write-Host "Validating path... Local directory detected."
                
                $volumeName=if($driveLetter.Length -le 2){$driveLetter+"\"}else{$driveLetter.Substring(0,3)}
                $GLOBAL:clusterSize=(Get-WmiObject -Class Win32_Volume | Where-Object {$_.Name -eq $volumeName}).BlockSize;
                write-host "Cluster size detected as $clusterSize."
                       
                $driveLettersOnThisComputer=ls function:[A-Z]: -n|?{test-path $_}
                if (!($driveLettersOnThisComputer -contains $path.SubString(0,2))){
                    Write-Host "The provided local path's first 2 characters do not match any volumes in this system.";
                    return $false;
                    }
                return $(isPathWritable $path)
                }else{
                        $regexUncPath="^\\(?:\\[^<>:`"/\\|?*]+)+$"
                                    if ($path -match $regexUncPath){
                        $GLOBAL:localPath=$False;
                        write-Host "UNC directory detected."
                        return $(isPathWritable $path)
                        }else{Write-Host "The provided path does not match a UNC pattern nor a local drive.";return $false;}
                        }
                }else{
                    Write-Host "The path $path currently does NOT exist";
                    Return $false;
                    }
            }
        
        if (validatePath){
            # Set variables
            $tempDirectory="$driveLetter`\getDiskSpeed"
            # New-Item -ItemType Directory -Force -Path $tempDirectory|Out-Null
            $testFile="$tempDirectory`\testfile.dat"
            $processors=(Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors
               
            # Ensure that diskspd.exe is available in the system
            $diskSpeedUtilityAvailable=get-command diskspd.exe -ea SilentlyContinue
            if (!($diskSpeedUtilityAvailable)){
                if (!(Get-Command choco.exe -ErrorAction SilentlyContinue)) {
                    Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
                    }    
                choco install diskspd -y;
                refreshenv;
            }  

        function getIops{
            # Sometimes, the test result throws this error "diskspd Error opening file:" if no switches were used
            # The work around is to specify more parameters
            # Other variations:
            # $testResult=diskspd.exe-d1 -o4 -t4 -b8k -r -L -w50 -c1G $testFile
            # $testResult=diskspd.exe -b4K -t1 -r -w50 -o32 -d10 -c8192 $testFile
            # Note: remove the -c option to avoid this error when running with unprivileged accounts
            # diskspd.exe : WARNING: Error adjusting token privileges for SeManageVolumePrivilege (error code: 1300)
            
            try{
                if ($localPath){
                    #$expression="diskspd.exe -b8k -d1 -o$processors -t$processors -r -L -w25 -c1G $testfile";
                    $expression="Diskspd.exe -b$clusterSize -d1 -h -L -o$processors -t1 -r -w30 -c1G $testfile  2>&1";
                    }else{
                        $expression="Diskspd.exe -b8K -d1 -h -L -o$processors -t1 -r -w30 -c1G $testfile 2>&1";
                        }
                #write-host $expression
                $testResult=invoke-expression $expression;
                <# diskspd.exe -b8k -d1 -o4 -t4 -r -L -w25 -c1G $testfile
                8K block size; 1 second random I/O test;4 threads; 4 outstanding I/O operations;
                25% write (implicitly makes read 75% ratio); 
                #>
                }
                catch{                    
                    $errorMessage = $_.Exception.Message
                    $failedItem = $_.Exception.ItemName
                    Write-Host "$errorMessage $failedItem";
                    continue;
                    }
            $x=$testResult|select-string -Pattern "total*" -CaseSensitive|select-object -First 1|out-String
            $iops=$x.split("|")[-3].Trim()
            #$mebibytesPerSecond=$x.split("|")[-4].Trim()            
            return $iops
        }
        
        function selectHighIops{
            $testArray=@();            
            for($i=1;$i -le $sampleSize;$i++){
                try{
                    $iops=getIops;
                    write-host "$i of $sampleSize`: $iops IOPS";
                    $testArray+=$iops;
                    }
                    catch{
                        $errorMessage = $_.Exception.Message
                        $failedItem = $_.Exception.ItemName
                        Write-Host "$errorMessage $failedItem";
                        break;
                    }
                }
            $highestResult=($testArray|measure -Maximum).Maximum
            return $highestResult
        } 
        
        # Trigger several tests and select the highest value
        $selectedIops=selectHighIops

        # Cleanup
        # cmd /c rd $tempDirectory
        function isFileLocked{
            param($file=$(New-Object System.IO.FileInfo $testFile))
            if (Test-Path $testFile){
                try {
                    $fileHandle = $file.Open([System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
                    if ($fileHandle){
                        # File handle is open, which means file is not locked
                        $fileHandle.Close()
                        }
                    return $false
                    }
                catch{
                    # file is locked
                    return $true
                    }
                }else{return $false}
            }
        
        do {
            sleep 1;
            isFileLocked|out-null;
            }until(!(isFileLocked))
        Remove-Item -Recurse -Force $tempDirectory
        
        $mebibytesPerSecond=[math]::round($(([int]$selectedIops)/128),2)
        return "Highest: $selectedIops IOPS ($mebibytesPerSecond MiB/s)";
        }else{return "Cannot get disk speed"}
    }

    function internetSpeedTest{
        $10MbFile="http://ipv4.download.thinkbroadband.com/10MB.zip"
        $time=Measure-Command {[void](Invoke-WebRequest $10MbFile –UseBasicParsing|out-Null) }
        # Used switch -UseBasicParsing to overcome this potential error:
        # Invoke-WebRequest : The response content cannot be parsed because the Internet Explorer engine is not available, 
        # or Internet Explorers first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again
        $speed=10/$time.TotalSeconds;
        $mbps=$speed*8.38861
        return "$([math]::Round($speed,2)) Mebibytes/sec ($([math]::Round($mbps,2)) Megabits/sec)"
    }

    function getContainer{
        param(
            $domainAdminCred
            )   
        if ((gwmi win32_computersystem).partofdomain -eq $true){            
                if (!(Get-Module ActiveDirectory)){
                    try {
                        $voidOutput=[void](Import-Module ServerManager -ErrorAction SilentlyContinue)
                        $voidOutput=[void](Add-WindowsFeature RSAT-AD-PowerShell -Confirm:$false);
                
                        ######## Error ######
                        #Error on some systems
                        #Add-WindowsFeature : The target of the specified cmdlet cannot be a Windows client-based operating system.
                        #At line:1 char:1
                        #+ Add-WindowsFeature RSAT-AD-PowerShell -Confirm:$false
                        #+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                        #    + CategoryInfo          : DeviceError: (localhost:String) [Install-WindowsFeature], Exception
                        #    + FullyQualifiedErrorId : WindowsClient_NotSupported,Microsoft.Windows.ServerManager.Commands.AddWindowsFeatureCommand
                        #
                        #Get-ADComputer : Unable to contact the server. This may be because this server does not exist, it is currently down,
                        #or it does not have the Active Directory Web Services running.
                        #At line:1 char:1
                        #+ Get-ADComputer $env:computername
                        #+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                        #    + CategoryInfo          : ResourceUnavailable: (SHERVER007:ADComputer) [Get-ADComputer], ADServerDownException
                        #    + FullyQualifiedErrorId : ActiveDirectoryServer:0,Microsoft.ActiveDirectory.Management.Commands.GetADComputer
                        #
                        # 
                        # Resolution:
                        # Get-ADComputer $env:computername -Server $DomainController -Credential (get-credential)
                        ######################

                        $voidOutput=[void](Import-Module ActiveDirectory -ErrorAction SilentlyContinue)
                        }catch{Continue;}

                    ##### Error when executing remotely ###
                    #WARNING: Error initializing default drive: 'Unable to contact the server. This may be because this server does not exist,
                    #it is currently down, or it does not have the Active Directory Web Services running.'.

                    }
                [string]$nearestDc=(Get-ADDomainController -Discover).HostName
                $result=[string](Get-ADComputer $env:computername -Server $nearestDc -Credential $domainAdminCred).DistinguishedName -Replace "^CN=[^,]+,",'' 
                }else{
                    $result="This computer is not domain joined."
                    }
                return $result
        }

    # Initialize variables
    $computerObject=New-Object PSObject
    $ips="Unknown";
    $machineType="Unknown";
    $machineModel="Unknown";
    $serial="Unknown";
    $os="Unknown";
    $cpu=$cpuLoad="Unknown";
    $memory="Unknown";
    $volumes="Unknown";
    $lastUpdate="Unknown";
    $antivirusName="Unknown";
    $activationStatus="Unknown";
    $cpuObject=@();
    $servicesWithDefaultAdministrator="";
    $winDefenderStatus="";
    $rdpSecurity="";
    $spectreVulnerability="";
    $otherVulnerabilities="";
    $localAdministrators="";
    $lastLogonUsers=@();
    $currentlyLogonUsers="";
    $topProcesses="";
    $memoryUsagePerUser="";    
    $container="";
    $certs="";
    $installedApps="";
    $autoStartServices="";
    $smbShares="";
    $kbs="";
    $gateway="";
    $publicIP="";
    $dns="";
    $pageFiles="";
    $currentSendReceive=@();
    $internetDownloadSpeed=0;
    $osArchitecture="";

    try{
        $ips=([System.Net.Dns]::GetHostAddresses($env:computername)|?{$_.AddressFamily -eq "InterNetwork"}|%{$_.IPAddressToString;}|out-string).Trim();
        $gateway=(Get-WmiObject -Class Win32_IP4RouteTable|where{ $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'}).nexthop
        $dns=Get-DnsClientServerAddress | Select-Object –ExpandProperty ServerAddresses|sort-object -Unique
        $publicIP=(Invoke-WebRequest -URI ("ifconfig.me/ip")).Content
        # $publicIP=(Invoke-RestMethod http://ipinfo.io/json -ea SilentlyContinue| Select -exp ip).Trim()
        # ipinfo.io is currently being blocked by many web filters
        <# Error
        System error 1312 has occurred.
        + CategoryInfo          : NotSpecified: (System error 1312 has occurred.:String) [], RemoteException
        + FullyQualifiedErrorId : NativeCommandError
        + PSComputerName        : SERVER01
 
        A specified logon session does not exist. It may already have been terminated.
        at <ScriptBlock>, <No file>: line 535
        at <ScriptBlock>, <No file>: line 3
        #>
        $internetDownloadSpeed=internetSpeedTest
        write-host $internetDownloadSpeed;
        $machineModel=(Get-WmiObject -Class Win32_ComputerSystem -ea stop).Model
        write-host $machineModel
        $serial=(Get-WMIObject -Class Win32_BIOS).SerialNumber
        write-host $serial
        $cpuObject = Get-WmiObject win32_processor -ea stop |select Name,NumberOfCores,LoadPercentage
        $cpu=($cpuObject|select Name,NumberOfCores|ft -AutoSize|Out-String).Trim()
        write-host $cpu
        $cpuLoad = ($cpuObject|  Measure-Object -property LoadPercentage -Average | Select @{Name="CurrentLoad";Expression={"{0:N2} %" -f ($_.Average)}}).CurrentLoad
        write-host $cpuLoad
        #$osArchitecture=(wmic os get osarchitecture)[2] # shows: 32-bit or 64-bit
        $osArchitecture=$ENV:PROCESSOR_ARCHITECTURE # shows: x86 or AMD64
        write-host $osArchitecture
        $osAndMemory = gwmi -Class win32_operatingsystem -ea stop| select @{Name="os";Expression={$_.Caption}},@{Name="Memory";Expression={"{0:N2} GB" -f ($_.TotalVisibleMemorySize / 1048576)}},@{Name = "Utilization"; Expression = {"{0:N2} %" -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize) }}
        if($osAndMemory){
            $os=$osAndMemory.os;
            $memory=$osAndMemory.Memory;
            $memoryUtilization=$osAndMemory.Utilization;
            }
        write-host "$os`r`n$memory`r`n$memoryUtilization"
        $volumes = (gwmi -Class win32_volume -Filter "DriveType!=5" -ea stop| ?{$_.DriveLetter -ne $null}|`
                    Select-object @{Name="Letter";Expression={$_.DriveLetter}},`
                    @{Name="Label";Expression={$_.Label}},`
                    @{Name="Capacity";Expression={"{0:N2} GiB" -f ($_.Capacity/1073741824)}},`
                    @{Name = "Available"; Expression = {"{0:N2} GiB" -f ($_.FreeSpace/1073741824)}},`
                    @{Name = "Utilization"; Expression = {"{0:N2} %" -f  ((($_.Capacity-$_.FreeSpace) / $_.Capacity)*100)}},`
                    @{Name = "diskBrand"; Expression = {(($_).getrelated().getrelated('Win32_DiskDrive')).caption}},`
                    # List disks brand and models
                    #((gwmi -Class Win32_logicaldisk).getrelated('Win32_DiskPartition').getrelated('Win32_DiskDrive')).caption.replace("USB Device","")
                    @{Name = "diskSpeed"; Expression = {getDiskSpeed $_.DriveLetter}}`
                    | ft -autosize | Out-String).Trim()
        write-host $volumes

        $pageFiles=Get-CimInstance -Class Win32_PageFileUsage|%{"$($_.Name) Allocated: $($_.AllocatedBaseSize) MB CurrentUsage: $($_.CurrentUsage) MB PeakUsage: $($_.PeakUsage) MB"}
        write-host $pageFiles
        $activationStatus=Get-ActivationStatus
        write-host $activationStatus
        #[string]$lastUpdate=gwmi win32_quickfixengineering |select HotFixID,InstalledOn|Select-Object -first 1
        $lastUpdate=(Get-HotFix | Measure-Object InstalledOn -Maximum).Maximum.ToString().Trim()
        write-host $lastUpdate
        $kbs=get-hotfix|select InstalledOn,HotFixID,InstalledBy|sort-object -Property InstalledOn -Desc|ft -AutoSize #|Select-Object -first 10 
        write-host $kbs
        $antivirusName=getAntivirusName
        write-host $antivirusName
        
        $servicesWithDefaultAdministrator=if((gwmi win32_computersystem).partofdomain -eq $true){
                                                checkServiceAccount $defaultDomainAdmin|Out-String|%{$_.Trim()} 
                                                }else{
                                                    checkServiceAccount 'Administrator'|Out-String|%{$_.Trim()}
                                                    }
        write-host $servicesWithDefaultAdministrator
        $localAdministrators=(net localgroup administrators | where {$_ -AND $_ -notmatch "command completed successfully"}|select -skip 4|Out-String).Trim()         
        write-host $localAdministrators
        $winDefenderStatus=(getWinDefenderStatus|Out-String).Trim();
        write-host $winDefenderStatus
        $rdpSecurity=(checkRDP|Out-String).Trim();
        write-host $rdpSecurity
        $spectreVulnerability=(checkSpectreVulnerability|Out-String).Trim();
        write-host $spectreVulnerability
        $otherVulnerabilities=(checkOtherVulnerabilities|Out-String).Trim();                
        write-host $otherVulnerabilities
        $lastLogonEvents=Get-WmiObject -Class Win32_UserProfile | Sort-Object -Property LastUseTime -Descending |?{$_.SID -notmatch "(S-1-5-18|S-1-5-19|S-1-5-20)"} | Select-Object -First 10
        if ($lastLogonEvents){
            $usersCount=$lastLogonEvents.Length;
            $lastLogonUsers=@();
            for ($i=0;$i -lt $usersCount; $i++){
                
                try{
                    $user=(New-Object System.Security.Principal.SecurityIdentifier($lastLogonEvents[$i].SID)).Translate([System.Security.Principal.NTAccount]).Value
                    }
                catch{
                    $user=$lastLogonEvents[$i].SID
                    }                    
                <# Try-Catch had worked around this error
                Exception calling "Translate" with "1" argument(s): "Some or all identity references could not be translated."
                At line:2 char:17
                +                 $userObject.Translate([System.Security.Principal.NTAccount]).Val ...
                +                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
                    + FullyQualifiedErrorId : IdentityNotMappedException
                #>               

                $count=$i+1;                 
                #$logonTime=([WMI]'').ConvertToDateTime($lastLogonEvents[$i].LastUseTime)
                $logonTime=$lastLogonEvents[$i].LastUseTime
                $lastLogonUsers+=@("$count`: $user $logonTime");

                }
            }        
        write-host $lastLogonUsers
        $currentlyLogonUsers=query user|Out-String
        write-host $currentlyLogonUsers
        #$topProcesses=(get-process|Group-Object -Property ProcessName | Select-Object -First 10 |Select Name, @{N='Memory (MB)';E={[math]::Round((($_.Group|Measure-Object WorkingSet -Sum).Sum / 1MB),2)}} | Sort-Object -Property "Memory (MB)" -Descending|ft -AutoSize| Out-String).Trim();
        $topProcesses=(get-process|Group-Object -Property ProcessName | Select Name, @{N='Memory (MB)';E={[math]::Round((($_.Group|Measure-Object WorkingSet -Sum).Sum / 1MB),2)}} | Sort-Object -Property "Memory (MB)" -Descending|Select-Object -First 10 |ft -AutoSize| Out-String).Trim();
        write-host $topProcesses
        $memoryUsagePerUser=(get-wmiobject win32_process|select @{N='User';E={$_.getowner().user}}, WorkingSetSize  | group user|select Name, @{N='Memory (MB)';E={[math]::Round(($_.Group.WorkingSetSize  | Measure-Object -Sum).Sum / 1Mb,2)  }}|sort-object -property "Memory (MB)" -Descending|ft -AutoSize| Out-String).Trim();
        write-host $memoryUsagePerUser 
        $container=getContainer -domainAdminCred $adminCredential             
        write-host $container
        $certObjects=Get-ChildItem -Path cert:\LocalMachine\My
        foreach ($cert in $certObjects){$certs+="$($cert.Thumbprint) $($cert.Subject)"}
        write-host $certs
        $smbShares=get-smbshare|ft -AutoSize
        write-host $smbShares
        $autoStartServices=(Get-WmiObject -ClassName Win32_Service -Filter "StartMode='Auto'"|Format-Table Name,StartName,State -AutoSize|out-String).Trim()
        write-host $autoStartServices
        $installedApps=Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object InstallDate,DisplayName, DisplayVersion, Publisher | Sort-Object -Property InstallDate -Descending |?{$_.DisplayName.length -gt 1 }|ft -AutoSize;
        write-host $installedApps
        #$regexOU=".+?(?=,),(.*)\."            
        #[string]$disabledComputersOu=(Get-ADOrganizationalUnit -Filter 'Name -like "Disabled Computers"'|select DistinguishedName).DistinguishedName
        #$container=Get-ADComputer $env:computername | Move-ADObject -TargetPath $disabledComputersOu -WhatIf -PassThru | Out-String   
        }
    catch{
        Write-Host $_.ScriptStackTrace;
        continue;
        }
    finally{
        if(!($machineModel)){$machineModel="Unknown"};
        if(!($machineType)){$machineType="Unknown"};
        if(!($osAndMemory)){$os=$memory=$memoryUtilization="Unknown";}
        if(!($ips)){$ips="Unknown";}
        if(!($cpuObject)){$cpu=$cpuLoad="Unknown";}
        if(!($volumes)){$volumes="Unknown";}
        if(!($serial)){$serial="Unknown"}
        if(!($certs)){$certs="None"}
        if(!($servicesWithDefaultAdministrator)){$servicesWithDefaultAdministrator="None"}
	    switch -wildcard ($machineModel){
            "VMware*" {$machineType="VMWare Virtual Machine";$hostname="ESXi host has not been setup to pass the host's machine.id to guest. Hence, hostname cannot be retrieved from inside $env:computername";}
		    "Virtual Machine" {$machineType="Hyper-V Virtual Machine";$hostname=getHyperVHostname}
		    "*HVM*" {$machineType="AWS Virtual Machine";$hostname="N/A";}
            "*.*" {$machineType="AWS Virtual Machine";$hostname="N/A";}	        
            default {$machineType="Unknown";$hostname="Unknown";}
		}
    <#
    "Name: $name";"IPs: $ips";"Machine Type: $machineType";"Hostname: $hostname";"Model: $machineModel";"Serial: $serial";"OS: $os";
    "Activation Status: $activationStatus";"CPU: $cpu";"CPU Load: $cpuLoad";"Memory: $memory";"Memory Utilization: $memoryUtilization";
    "Top Processes: $topProcesses";"Memory Usage Per User: $memoryUsagePerUser";"Volumes: $volumes";"Container: $container";"Last Update: $lastUpdate";
    "Antivirus Name: $antivirusName";"Local Admins: $localAdministrators";"Services with default Domain Admin: $servicesWithDefaultAdministrator";
    "WinDefender Status: $winDefenderStatus";"RDP Security: $rdpSecurity";"Spectre Vulnerability: $spectreVulnerability"; "Other Vulnerabilities: $otherVulnerabilities";
    "Last Logon Users: $lastLogonUsers";"Last Logon Times: $lastLogonTimes";
    #>             
        $computerObject | Add-Member -MemberType NoteProperty -Name "Name" -Value $name
        $computerObject | Add-Member -MemberType NoteProperty -Name "ips" -Value $ips
        $computerObject | Add-Member -MemberType NoteProperty -Name "gateway" -Value $($gateway|Out-String).Trim()
        $computerObject | Add-Member -MemberType NoteProperty -Name "dns" -Value $($dns|Out-String).Trim()
        $computerObject | Add-Member -MemberType NoteProperty -Name "publicIP" -Value $publicIP
        $computerObject | Add-Member -MemberType NoteProperty -Name "internetDownloadSpeed" -Value $internetDownloadSpeed
        $computerObject | Add-Member -MemberType NoteProperty -Name "machineType" -Value $machineType
        $computerObject | Add-Member -MemberType NoteProperty -Name "hostname" $hostname
        $computerObject | Add-Member -MemberType NoteProperty -Name "machineModel" -Value $machineModel
        $computerObject | Add-Member -MemberType NoteProperty -Name "serial" -Value $serial
        $computerObject | Add-Member -MemberType NoteProperty -Name "os" -Value $os
        $computerObject | Add-Member -MemberType NoteProperty -Name "osArchitecture" -Value $osArchitecture
        $computerObject | Add-Member -MemberType NoteProperty -Name "activationStatus" -Value $activationStatus
        $computerObject | Add-Member -MemberType NoteProperty -Name "cpu" -Value $($cpu|out-string).Trim()
        $computerObject | Add-Member -MemberType NoteProperty -Name "cpuUtilization" -Value $cpuLoad
        $computerObject | Add-Member -MemberType NoteProperty -Name "memory" -Value $memory
        $computerObject | Add-Member -MemberType NoteProperty -Name "memoryUtilization" -Value $memoryUtilization
        $computerObject | Add-Member -MemberType NoteProperty -Name "topProcesses" -Value $($topProcesses|out-string).Trim()
        $computerObject | Add-Member -MemberType NoteProperty -Name "memoryUsagePerUser" -Value $($memoryUsagePerUser|out-string).Trim()         
        $computerObject | Add-Member -MemberType NoteProperty -Name "volumes" -Value $volumes
        $computerObject | Add-Member -MemberType NoteProperty -Name "pageFiles" -Value $pageFiles
        $computerObject | Add-Member -MemberType NoteProperty -Name "container" -Value $container
        $computerObject | Add-Member -MemberType NoteProperty -Name "antivirus" -Value $antivirusName
        $computerObject | Add-Member -MemberType NoteProperty -Name "localAdministrators" -Value $localAdministrators
        $computerObject | Add-Member -MemberType NoteProperty -Name "servicesWithDefaultAdministrator" -Value $servicesWithDefaultAdministrator
        $computerObject | Add-Member -MemberType NoteProperty -Name "winDefenderStatus" -Value $winDefenderStatus
        $computerObject | Add-Member -MemberType NoteProperty -Name "rdpSecurity" -Value $rdpSecurity
        $computerObject | Add-Member -MemberType NoteProperty -Name "spectreVulnerability" -Value $spectreVulnerability
        $computerObject | Add-Member -MemberType NoteProperty -Name "otherVulnerabilities" -Value $otherVulnerabilities
        $computerObject | Add-Member -MemberType NoteProperty -Name "lastLogonUsers" -Value $($lastLogonUsers|out-string).Trim();
        $computerObject | Add-Member -MemberType NoteProperty -Name "currentlyLogonUsers" -Value $currentlyLogonUsers.Trim()
        $computerObject | Add-Member -MemberType NoteProperty -Name "certs" -Value $certs
        $computerObject | Add-Member -MemberType NoteProperty -Name "smbShares" -Value $($smbShares|Out-String).Trim()
        $computerObject | Add-Member -MemberType NoteProperty -Name "autoStartServices" -Value $autoStartServices
        $computerObject | Add-Member -MemberType NoteProperty -Name "installedApps" -Value $($installedApps|Out-String).Trim();
        $computerObject | Add-Member -MemberType NoteProperty -Name "lastUpdate" -Value $lastUpdate
        $computerObject | Add-Member -MemberType NoteProperty -Name "kbs" -Value $($kbs|Out-String).Trim()       
        }
    return $computerObject;
    # $GLOBAL:computerObjects+=,$computerObject
}

function executeFunctionRemotely{
    param(
        $remoteComputer,
        $credential
        )
    
    do{
        $session = New-PSSession -ComputerName $remoteComputer
        "Connecting to remote computer $remoteComputer..."
        sleep -seconds 5
        if ($session){"Connected."}
        } until ($session.state -match "Opened")

    invoke-command -session $session -scriptblock{
                                                param($checkWindows,$cred)
                                                [ScriptBlock]::Create($checkWindows).invoke($env:computername,$cred);
                                                #invoke-command -Credential $Using:cred -ScriptBlock $checkWindows                                        
                                                } -args ${function:checkWindows},$credential
    Remove-PSSession -id $session.Id
    }

executeFunctionRemotely -remoteComputer $remoteComputer -credential $adminCredential

<# Sample output
Name                             : REMOTESHERVER009
ips                              : 192.168.1.10
                                   169.254.4.82
gateway                          : 192.168.1.1
dns                              : 192.168.1.1
                                   8.8.8.8
publicIP                         : 165.555.555.555
internetDownloadSpeed            : 3.49 Mebibytes/sec (29.27 Megabits/sec)
machineType                      : Unknown
hostname                         : Unknown
machineModel                     : UCSB-B200-M5
serial                           : LALALA
os                               : Microsoft Windows Server 2016 Datacenter
osArchitecture                   : AMD64
activationStatus                 : Licensed
cpu                              : Name                                     NumberOfCores
                                   ----                                     -------------
                                   Intel(R) Xeon(R) Gold 5120 CPU @ 2.20GHz            14
                                   Intel(R) Xeon(R) Gold 5120 CPU @ 2.20GHz            14
cpuUtilization                   : 1.00 %
memory                           : 574.66 GB
memoryUtilization                : 1.64 %
topProcesses                     : Name                     Memory (MB)
                                   ----                     -----------
                                   svchost                       706.11
                                   rhs                           234.64
                                   WmiPrvSE                      213.25
                                   wsmprovhost                    211.1
                                   MsMpEng                       196.69
                                   lsass                          54.36
                                   Nimble.ConnectionService        52.8
                                   nimble.hotfixmonitor            51.8
                                   clussvc                        48.55
                                   LogonUI                        42.39
memoryUsagePerUser               : Name            Memory (MB)
                                   ----            -----------
                                   SYSTEM              1163.13
                                   NETWORK SERVICE      443.85
                                   176233               211.29
                                   LOCAL SERVICE         140.9
                                   DWM-1                 30.68
                                                          0.14
volumes                          : Letter Label Capacity   Available  Utilization diskBrand                                                                                                                                       
                                                   diskSpeed          
                                   ------ ----- --------   ---------  ----------- ---------                                                                                                                                       
                                                   ---------          
                                   C:           445.55 GiB 382.59 GiB 14.13 %     {LSI UCSB-MRAID12G-HE SCSI Disk Device, Nimble Server  Multi-Path Disk Device, Nimble Server  Multi-Path Disk Device, Nimble Server  Multi-Path 
                                   Disk Device...} 1067.12 MiB/s (1...
pageFiles                        : C:\pagefile.sys Allocated: 43008 MB CurrentUsage: 0 MB PeakUsage: 0 MB
antivirus                        : MsMpEng.exe
localAdministrators              : Administrator
servicesWithDefaultAdministrator : None
winDefenderStatus                : It has been 0 day(s) between Last Update: 12/25/2019 14:28:20 and New Release: 12/26/2019 2:14:01 AM
                                   Excellent! Malware Antivirus Definition 1.307.1154.0 on this computer matches the Microsoft release.
rdpSecurity                      : RDP Network Authentication Requirement: passed!
                                   RDP Encryption Level: Client Compatible
spectreVulnerability             : System version: 10.0.14393.0 VS minimum version required: 10.0.14393.2842
                                   Spectre meltdown vulnerabilities: Pass
otherVulnerabilities             : CVE-2017-8529 FEATURE_ENABLE_PRINT_INFO_DISCLOSURE_FIX (32-Bit): Fail
                                   CVE-2017-8529 FEATURE_ENABLE_PRINT_INFO_DISCLOSURE_FIX (64-bit): Fail
                                   MS15-124-Critical ASLR Hardening Setting for IE (32-Bit): Fail
                                   MS15-124-Critical ASLR Hardening Setting for IE (64-Bit): Fail
                                   CVE-2017-5715 FeatureSettingsOverride: Fail
                                   CVE-2017-5715 FeatureSettingsOverrideMask: Fail
                                   CVE-2017-5753-54 MinVmVersionForCpuBasedMitigations: Fail
                                   Internet Explorer Overall: Fail
                                   Memory Management Registry Keys: Fail
                                   MS11-025 (MFC Remote Code Execution): Fail
                                   Unquoted Service Path Enumeration Vulnerabilities: Fail.
                                   LAPS is not installed.
                                   SNMP: permittedManagers and validCommunities values are NOT detected.
lastLogonUsers                   : 1: INTRANET\CUILO 20191226041129.721000+000
                                   2: INTRANET\NANG-ADMIN 20191011211258.684000+000
                                   3: INTRANET\DUDE555 20191006194507.747000+000
currentlyLogonUsers              : 
certs                            : None
smbShares                        : Name         ScopeName Path                                         Description  
                                   ----         --------- ----                                         -----------  
                                   A$           *         A:\                                          Default share
autoStartServices                : Name                      StartName                   State  
                                   ----                      ---------                   -----  
                                   BFE                       NT AUTHORITY\LocalService   Running
                                   BrokerInfrastructure      LocalSystem                 Running
                                   CDPSvc                    NT AUTHORITY\LocalService   Running
                                   ClusSvc                   LocalSystem                 Running
                                   CoreMessagingRegistrar    NT AUTHORITY\LocalService   Running
                                   CryptSvc                  NT Authority\NetworkService Running
                                   DcomLaunch                LocalSystem                 Running
                                   Dhcp                      NT Authority\LocalService   Running
                                   DiagTrack                 LocalSystem                 Running
                                   Dnscache                  NT AUTHORITY\NetworkService Running
                                   DPS                       NT AUTHORITY\LocalService   Running
                                   EventLog                  NT AUTHORITY\LocalService   Running
                                   EventSystem               NT AUTHORITY\LocalService   Running
                                   FontCache                 NT AUTHORITY\LocalService   Running
                                   gpsvc                     LocalSystem                 Running
                                   gupdate                   LocalSystem                 Stopped
                                   iphlpsvc                  LocalSystem                 Running
                                   LanmanServer              LocalSystem                 Running
                                   LanmanWorkstation         NT AUTHORITY\NetworkService Running
                                   LSM                       LocalSystem                 Running
                                   MapsBroker                NT AUTHORITY\NetworkService Stopped
                                   MpsSvc                    NT Authority\LocalService   Running
                                   MSDTC                     NT AUTHORITY\NetworkService Running
                                   MSiSCSI                   LocalSystem                 Running
                                   Netlogon                  LocalSystem                 Running
                                   Nimble Connection Service LocalSystem                 Running
                                   Nimble Hotfix Monitor     LocalSystem                 Running
                                   Nimble VSS Requestor      LocalSystem                 Running
                                   NlaSvc                    NT AUTHORITY\NetworkService Running
                                   nsi                       NT Authority\LocalService   Running
                                   PcaSvc                    LocalSystem                 Running
                                   Power                     LocalSystem                 Running
                                   ProfSvc                   LocalSystem                 Running
                                   RemoteRegistry            NT AUTHORITY\LocalService   Stopped
                                   RpcEptMapper              NT AUTHORITY\NetworkService Running
                                   RpcSs                     NT AUTHORITY\NetworkService Running
                                   SamSs                     LocalSystem                 Running
                                   Schedule                  LocalSystem                 Running
                                   SENS                      LocalSystem                 Running
                                   ShellHWDetection          LocalSystem                 Running
                                   Spooler                   LocalSystem                 Running
                                   sppsvc                    NT AUTHORITY\NetworkService Running
                                   SrmSvc                    LocalSystem                 Running
                                   SystemEventsBroker        LocalSystem                 Running
                                   Themes                    LocalSystem                 Running
                                   tiledatamodelsvc          LocalSystem                 Running
                                   TrkWks                    LocalSystem                 Running
                                   UALSVC                    LocalSystem                 Running
                                   UserManager               LocalSystem                 Running
                                   W32Time                   NT AUTHORITY\LocalService   Running
                                   WbioSrvc                  LocalSystem                 Stopped
                                   Wcmsvc                    NT Authority\LocalService   Running
                                   WinDefend                 LocalSystem                 Running
                                   Winmgmt                   localSystem                 Running
                                   WinRM                     NT AUTHORITY\NetworkService Running
                                   WpnService                LocalSystem                 Running
installedApps                    : InstallDate DisplayName                                                  DisplayVersion  Publisher            
                                   ----------- -----------                                                  --------------  ---------            
                                   20191218    Google Chrome                                                79.0.3945.88    Google LLC           
                                   20191213    Google Update Helper                                         1.3.35.421      Google LLC           
                                   20191011    TreeSize Free V4.3.1                                         4.3.1           JAM Software         
                                   20190821    Advanced IP Scanner 2.5                                      2.5.3850        Famatech             
                                               Intel(R) Chipset Device Software                             10.1.17903.8106 Intel(R) Corporation 
                                               HPE Nimble Windows Toolkit                                   7.0.0.31        HPE Nimble Storage   
                                               xplorer² lite 32 bit                                         4.2.0.1         Zabkat               
                                               Microsoft Visual C++ 2013 Redistributable (x64) - 12.0.30501 12.0.30501.0    Microsoft Corporation
lastUpdate                       : 12/13/2019 12:00:00 AM
kbs                              : InstalledOn            HotFixID  InstalledBy        
                                   -----------            --------  -----------        
                                   12/13/2019 12:00:00 AM KB4519998 NT AUTHORITY\SYSTEM
                                   10/13/2019 12:00:00 AM KB4521858 INTRANET\CUILO        
                                   10/3/2019 12:00:00 AM  KB4512574 INTRANET\CUILO        
                                   6/19/2019 12:00:00 AM  KB4503537 NT AUTHORITY\SYSTEM
                                   6/5/2019 12:00:00 AM   KB4498947 NT AUTHORITY\SYSTEM
                                   2/3/2018 12:00:00 AM   KB4049065 NT AUTHORITY\SYSTEM
PSComputerName                   : REMOTESHERVER009
RunspaceId                       : 7abf1c05-4641-4997-a521-b6e2f9db0973
#>