Powershell script to check where the Windows Server Paging File Location is on remote servers and export to .CSV

mjm21
mjm21 used Ask the Experts™
on
Powershell script to check where the Windows Server Paging File Location is on remote servers and export to .CSV
Project is to get a list of those servers that have the page file located on C:\ and other drives etc.  

IE:
Server C:
             D:
             E:
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Dustin SaundersCo-Founder and Chief Architect
Top Expert 2016
Commented:
That above will get pagefiles, but not output to a CSV.  Here I've completed the script to give you that function.  Just change the top 2 lines with the location of the servers you want to check and the place where you want the CSV to go.  In the servers.txt file, on each line put in the name of the server you want to check.

$serverFile = "C:\test\servers.txt"
$outputFile = "C:\test\pagefiles.csv"

#region ==============================================================================================================================================
#<copyright file="PageFileLocation.ps1">
#Author : mysticmukesh@gmail.com
#</copyright>
#----------------------------------------------------------------------------------------------------------------------------------------------
#Revision History
#================
#Date                Author        Comments
#----------------------------------------------------------------------------------------------------------------------------------------------
#03-July-2015        Mukesh-kumar         Initial version
#08-June-2016		 Mukesh-Kumar         Added parameter : serverlist 
#===============================================================================================================================================
<#

.SYNOPSIS

Retrieves  page file location information from  local or remote computers.

.DESCRIPTION

The script uses .Net RegistryKey class and its OpenRemoteBaseKey method to retrieve the information.

Each computer is contacted sequentially, not in parallel.

.EXAMPLE

Run it from the location where the script is stored.

PS C:\Users\Administrator\Downloads> .\PageFileLocation.ps1

ServerName                                                  PageFileLocation
----------                                                  ----------------
Server1                                                     C:\pagefile.sys

.EXAMPLE 

Read computer names from a file (one name per line) and retrieve their page file loction.

Get-PageFileLocation -serverlist (Get-Content C:\server.txt)

ServerName                              PageFileLocation
----------                              ----------------
PRASADMU23                              C:\pagefile.sys
NOTFOUND                                The network path was not found.

#>
#endregion
function Get-PageFileLocation()
{	
	[CmdLetBinding ()]
	param(
		[Parameter(Mandatory=$False)]
		[String[]]$serverlist
	)
	#Get the list of servers
#	$serverlist=get-content "C:\servers.txt" -ErrorAction SilentlyContinue
	if($serverlist -eq $null)
	{
		$serverlist=hostname
	}
	$a=@()
	#Regular Expression to extract the page file location from the registry key
	$Regex="^\\.{3}(.*)"
	$Object=New-Object PSObject 
	$Object1=New-Object PSObject 
	foreach ($server in $serverlist)
	{
		try
		{
			#Open the registry on multiple remote computers
			$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine',$server )
			$RegKeyPath= "SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management"
			$pageFileKey=$reg.OpenSubKey($RegKeyPath)
			$pageFileLocation=$pageFileKey.GetValue("ExistingPageFiles")
			if("$pageFileLocation" -match $Regex)
			{
				$pageFileLocation=$Matches[1]
				$Object | add-member Noteproperty ServerName $server -Force
				$Object | add-member Noteproperty PageFileLocation $pageFileLocation -Force
				$a+=$Object
			}
		}	
		Catch [Exception] # To capture the non reachable servers
		{
			[string]$ExcepMsg=$_.Exception.Message
			$Object1 | add-member Noteproperty ServerName $server -Force
			$Object1 | add-member Noteproperty PageFileLocation $ExcepMsg -Force
			$a+=$Object1
		}
	}
	Write-Output $a
}

Get-PageFileLocation -serverlist (Get-Content $serverFile) | Export-Csv $outputFile -NoTypeInformation

Open in new window

Most Valuable Expert 2018
Distinguished Expert 2018
Commented:
Here's a version that uses WMI and generates a more detailed output; you can optionally ...
* use -FailFast to ping machines before trying to query them,
* pass a Credentials object,
* pass a file to export the results to
If no export file is given, the results will end up in the pipeline and can be processed further as usual.
Pipeline input is supported, so you can do something like
Get-ADComputer -Filter * | .\Get-PageFileLocationByWmi.ps1 -FailFast | Format-Table -AutoSize

Open in new window

[CmdletBinding()]
Param(
	[Parameter(ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True, Position=0)]
	[Alias('ComputerName')][String[]]$Name = @($ENV:ComputerName),
	[Switch]$FailFast,
	[System.Management.Automation.PSCredential]$Credential,
	[String]$ExportCsv
)
Begin {
	$Results = @()
	$ResultProperties = 'Computername', 'SystemManaged', 'Name', 'InitialSize', 'MaximumSize', 'AllocatedBaseSize', 'CurrentUsage', 'PeakUsage', 'Exception'
	$WmiArgs = @{'Namespace' = 'root\cimv2'; 'ErrorAction' = 'Stop'}
	$Collect = @{}
	$Ping = New-Object -TypeName System.Net.NetworkInformation.Ping
	Function Set-ResultProperties($Hashtable, $Computername, $SystemManaged, $Name, $InitialSize, $MaximumSize, $AllocatedBaseSize, $CurrentUsage, $PeakUsage, $Exception) {
		If (-not $Hashtable.ContainsKey($Name)) {
			$Hashtable[$Name] = '' | Select-Object -Property $ResultProperties
		}
		ForEach ($Property In ($PSBoundParameters.Keys | Where-Object {$_ -ne 'Hashtable'})) {
			$Hashtable[$Name].$Property = $PSBoundParameters[$Property]
		}
	}
}
Process {
	ForEach ($Computer In $Name) {
		Try {
			$Collect.Clear()
			Write-Host -Object "Processing $($Computer) ... " -Foregroundcolor White -NoNewline
			If ($FailFast -and (($Ping.Send($Computer, 1000)).Status -ne "Success") -and (($Ping.Send($Computer, 500)).Status -ne "Success")) {
				Throw "Offline"
			}
			$WmiArgs['ComputerName'] = $Computer
			If ($Credential -and ($Computer.Split('.')[0] -ne $ENV:ComputerName)) {
				$WmiArgs['Credential'] = $Credential
			}
			$SystemManaged = (Get-WmiObject -Query "Select AutomaticManagedPagefile From Win32_ComputerSystem" @WmiArgs).AutomaticManagedPagefile -eq $True
			Get-WmiObject -Query "Select AllocatedBaseSize, CurrentUsage, Name, PeakUsage From Win32_PageFileUsage" @WmiArgs | ForEach-Object {
				Set-ResultProperties -Hashtable $Collect -Name $_.Name -ComputerName $Computer -SystemManaged $SystemManaged -AllocatedBaseSize $_.AllocatedBaseSize -CurrentUsage $_.CurrentUsage -PeakUsage $_.PeakUsage
			}
			If (-not $SystemManaged) {
				Get-WmiObject -Query 'Select InitialSize, MaximumSize, Name From Win32_PageFileSetting' @WmiArgs | ForEach-Object {
					Set-ResultProperties -Hashtable $Collect -Name $_.Name -ComputerName $Computer -SystemManaged $SystemManaged -InitialSize $_.InitialSize -MaximumSize $_.MaximumSize
				}
			}
			Write-Host -Object "OK" -Foregroundcolor Green
		} Catch {
			Set-ResultProperties -Hashtable $Collect -Name '' -ComputerName $Computer -Exception $_.Exception.Message
			Write-Host -Object "ERROR: $($_.Exception.Message)" -Foregroundcolor Red
		}
		ForEach ($Key In $Collect.Keys) {
			$Results += $Collect[$Key]
		}
	}
}
End {
	If ([string]::IsNullOrEmpty($ExportCsv)) {
		$Results | Sort-Object -Property ComputerName, Name
	} Else {
		$Results | Sort-Object -Property ComputerName, Name | Export-Csv -Path $ExportCsv -NoTypeInformation
	}
}

Open in new window

11/26 Forrester Webinar: Savings for Enterprise

How can your organization benefit from savings just by replacing your legacy backup solutions with Acronis' #CyberProtection? Join Forrester's Joe Branca and Ryan Davis from Acronis live as they explain how you can too.

Author

Commented:
Jeremy / Justin:  When running the script the results show only one server out of the pulled list of for example 10 servers.  Permissions are correct.  Any thoughts?

oBDA: Where in your script will it know how to pull from a list of servers from a .txt file?

Thanks all!
Most Valuable Expert 2018
Distinguished Expert 2018

Commented:
The script itself doesn't support it, but you can pass it any string array, like the AD example above:
Get-Content -Path C:\Temp\servers.txt | .\Get-PageFileLocationByWmi.ps1 -FailFast -ExportCsv C:\Temp\Pagefiles.csv

Open in new window

Or like this:
.\Get-PageFileLocationByWmi.ps1 -ComputerName (Get-Content -Path C:\Temp\servers.txt) -FailFast

Open in new window

Author

Commented:
Thanks! Appreciate all your efforts!
Dustin SaundersCo-Founder and Chief Architect
Top Expert 2016

Commented:
Asker appears to have gotten a working answer.  Suggested awarding points to the custom code contributions weighted for oBdA spending more time responding.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial