PowerShell: Optimize RAM on Remote Computers

# simultaneousExec_v0.01.ps1
# Requirement: must run as Administrator

$computerNames="SHERER1","SHERER2"

function installEmptyStandbyList{
$emptyStandbyListAvailable=(Get-Command EmptyStandbyList.exe -ErrorAction SilentlyContinue);
if(!($emptyStandbyListAvailable)){
# Set default protocol to TLS 1.2 and bypass certificate trust issues
$classTrustAllCerts = @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate,WebRequest request, int certificateProblem) {
return true;
}
}
"@
try{
Add-Type -TypeDefinition $classTrustAllCerts
$trustAllCertsPolicy=New-Object TrustAllCertsPolicy
[System.Net.ServicePointManager]::CertificatePolicy = $trustAllCertsPolicy
}catch{}
try{
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;
}catch{
[System.Net.ServicePointManager]::SecurityProtocol = [Enum]::ToObject([System.Net.SecurityProtocolType], 3072);
}
$fileName="EmptyStandbyList.zip"
$tempDir="C:\Temp";
$extractionDir="C:\Windows"
$source = "https://kimconnect.com/wp-content/uploads/2020/02/EmptyStandbyList.zip";
$destinationFile = "$tempDir\$fileName";
New-Item -ItemType Directory -Force -Path $tempDir;
$webclient = New-Object System.Net.WebClient;
$WebClient.DownloadFile($source,$destinationFile);
try{
Expand-Archive -LiteralPath $destinationFile -DestinationPath $extractionDir;
}catch{ # Legacy method for backward compatibility
$shell = New-Object -ComObject Shell.Application
$zipFile = $shell.NameSpace($destinationFile);
$destinationFolder = $shell.NameSpace($extractionDir);

$copyFlags = 0x00
$copyFlags += 0x04 # Hide progress dialogs
$copyFlags += 0x10 # Overwrite existing files

$destinationFolder.CopyHere($zipFile.Items(), $copyFlags)
}
# copy $destinationFile "$extractionDir\$fileName"
# Validation
$emptyStandbyListIsInstalled=(Get-Command EmptyStandbyList.exe -ErrorAction SilentlyContinue);
if ($emptyStandbyListIsInstalled){
write-host "EmptyStandbyList.exe has been added into environmental path of $extractionDir successfully."
}else{
write-host "There was an error preventing EmptyStandbyList.exe from being installed onto this system.";
break;
}
}else{
write-host "EmptyStandbyList.exe is already available in this system.`n";
}
}

function optimizeRam{
(EmptyStandbyList.exe standbylist)+(EmptyStandbyList.exe modifiedpagelist)+(EmptyStandbyList.exe workingsets);
# Get RAM utilization after 1 minute
$null=ping -n 60 localhost 2>&1
$osAndMemory = gwmi -Class win32_operatingsystem -ea stop| select @{Name="computername";Expression={$env:computername}},@{Name="os";Expression={$_.Caption}},@{Name="Memory";Expression={"{0:N2} GB" -f ($_.TotalVisibleMemorySize / 1048576)}},@{Name = "Utilization"; Expression = {"{0:N2} %" -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize) }}
return $osAndMemory
}

# Limitation: this function currently only takes one function with multiple parameters (that are not nested functions)
function execFunctionAsJob{
param($computername,$functionName,$parameters)
#$scriptBlock=${function:$functionName} # another method to retrieve the inside codes of a provided function
$scriptBlock=(Get-Command $functionName -CommandType Function).Definition;

<# Alternative method
$session=new-pssession -ComputerName $computername
$job=invoke-command -Session $session -ScriptBlock{
param ($importedFunction,$params)
return [ScriptBlock]::Create($importedFunction).invoke($params);
} -args $scriptBlock,$parameters
Remove-PSSession $session
#>
$job=invoke-command -ComputerName $computername -ScriptBlock{
param ($importedFunction,$params)
return [ScriptBlock]::Create($importedFunction).invoke($params);
} -args $scriptblock,$parameters -AsJob
return $job
}

function simultaneousExec{
param($computerNames,$functionName,$parameters)
$timer=[System.Diagnostics.Stopwatch]::StartNew();
$jobIds=@()
foreach ($computer in $computerNames){
$job=execFunctionAsJob -computername $computer -functionName $functionName -parameters $parameters
#$job=execFunctionAsJob -computername $computer -functionName "pingSomething" -parameters "yahoo.com","google.com"
$jobIds+=,$job.Id
}
Wait-Job -Id $jobIds;
$jobResults=Receive-Job -Id $jobIds;
Remove-Job -id $jobIds;
$time=[math]::round($timer.Elapsed.TotalHours,2);
$timer.Stop();
$timer.Reset();
$closingMessage="`r`nOverall Time: $time hours"
write-host $closingMessage;

return $jobResults
}

simultaneousExec -computerNames $computerNames -functionName "installEmptyStandbyList"
simultaneousExec -computerNames $computerNames -functionName "optimizeRam"

<# Manual trigger on a localhost: just run these 2 functions
installEmptyStandbyList
optimizeRam
#>

Leave a Reply

Your email address will not be published. Required fields are marked *