Monitoring disk space utilization of server(s) is the critical and important job for any administrator. Keeping things organized might improve application availability and server availability. This article takes us through the in-detail steps to read each drive and report every drive details based on threshold values and output data written into a CSV file. The step by step process quickly take us through the disk space utilization details of the server(s). You'll basically feed a list of servers to watch over, and it will report back on these for you, meaning you could also use it as a more general "daily server disk space report"
↑ Return to Top
This article talks about the use of credentials. The credentials can be used to query external servers which have the trust relationship between the domains. Also, list various methods to secure the password. The process iterates through a list of servers and drives that you have listed in a CSV file. Checking for disk space status of every listed drive and its status may fall under one of the four statuses that are defined as critical, warning, low and good. If the disk in a question of below the threshold then the corresponding status is updated. The nice thing about this script is that it will consolidate health status of each listed disks and gives a summary that needs your attention (you set the threshold as per requirement because the size of the drive may vary from server to server).
Get-credential always pop-up dialog box for entering a password, however, you can save your securestring password to a file or directly feed the password. The problem with this is that the password will be exposed to anyone with access to the file.
The Get-Credential displays a window to enter credential details. This will appear every time when you run the script.The $credential variable store the username and password. It's then fed to the respective queries for further processing.
clear
$credential = Get-Credential
foreach ( $args in get-Content c:\server.txt ) {
get-WmiObject win
32
_logicaldisk -Credential $credential -ComputerName $args -Filter
"Drivetype=3"
|
ft SystemName,DeviceID,VolumeName,@{Label=
"Total SIze"
;Expression={$_.Size /
1
gb -as [int] }},@{Label=
"Free Size"
;Expression={$_.freespace /
gb -as [int] }} -autosize
}
The password is hardcoded in the script. Of course, the problem with this is that your password will be exposed to anyone with access to the script file.
$User =
'hqnt\abcd'
$Pass = ConvertTo-SecureString
'abcd@2015'
-AsPlainText -Force
$Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User,$Pass
_logicaldisk -ComputerName $args -Credential $Credentials -Filter
First, password has to be written to a file
ps:\>read-host -AsSecureString |ConvertFrom-SecureString |Out-File C:\SecurePassword.txt
Second, the credentials are read from the file using PSCredential class. You don't need to re-enter the password over and over again.
'hqnt\abcdv'
$pass= cat C:\passwordstring.txt |ConvertTo-SecureString
_logicaldisk -ComputerName $args -Credentials $cred -Filter
_logicaldisk -ComputerName $args -Filter
https://gallery.technet.microsoft.com/PowerShell-CSV-Disk-Space-5992fb49
Server,Drive,LowTh,WarnTh,CritTh
HQDBSP00
8
,E:,
,
5
3
,F:,
20
18
,G:,
HQSPDB99
01
HQSPDB09
HQSPDB80
For example, The first example writes a simple message with a default state to a log file abc.log. In the second example, a message along with "Error" state details are entered into the log file.
1.
.EXAMPLE
2.
PS:\> Write-Log -Message
"Server is reachable and starting the process "
-Logfile c:\PowerSQL\abc.log
3.
2
4.
PS:\> Write-Log -
level
Error -Message
"Server is not reachable "
The below function can be reused to in any of the PoSH code. Also, the output file will be used for troubleshooting and activity progress tracking.
01.
Function Write-Log {
02.
[CmdletBinding()]
03.
Param(
04.
[Parameter(Mandatory=$False)]
05.
[ValidateSet(
"INFO"
"WARN"
"ERROR"
)]
06.
[String]
07.
$Level =
08.
09.
[Parameter(Mandatory=$True)]
10.
[string]
11.
$Message,
12.
13.
14.
15.
$logfile
16.
)
17.
18.
$Stamp = (Get-Date).toString(
"yyyy/MM/dd HH:mm:ss"
19.
$Line =
"$Stamp $Level $Message"
20.
If($logfile) {
21.
Add-Content $logfile -Value $Line
22.
23.
Else {
24.
Write-Output $Line
25.
26.
This below code defines the output file location, output log file location, and directory to save the output. The $date variable hold the date formatting part. It's then appended to the $logfilename and $outputfile name to generate a more meaningful filename. For example, DiskSpaceLog_2016-10-10 and DiskSpace_CSV_2016-10-5
$date=Get-Date -format "yyyy-MM-d"
$date=Get-Date -
format
"yyyy-MM-d"
#Prepare log file and output CSV file
$LogFileName=
"DiskSpaceLog_$($date)"
$Filename=
"DiskSpace_CSV_$($date)"
This portion of code decides whether to pass credentials or not. The Get-credential always pop-up dialog box for entering a password, however, you can save your securestring password to a file or directly feed the password. The problem with this is that the password will be exposed to anyone with access to the file. If you want to use the default login credentials then you don't need to mention anything in the code. You can comment the line of code.
'abcd'
''
abcd@
#2016
' -AsPlainText -Force
$diskinfo= Get-WmiObject -Class Win
_LogicalDisk -ComputerName $cserver -Filter
"DeviceID='$cdrivelt'"
ForEach ($disk in $diskinfo)
{
#Calculate the % free. This parameter will be compared with various thresholds to derive the status of the drive
If ($diskinfo.Size -gt
0
) {$percentFree = [Math]::round((($diskinfo.freespace/$diskinfo.size) *
100
))}
Else {$percentFree =
#Determine if disk needs to be flagged for warning or critical alert
If ($percentFree -le $ccritth) { $status =
"Critical"
ElseIf ($percentFree -gt $ccritth -AND $percentFree -le $cwarnth) { $status =
"Warning"
ElseIf ($percentFree -ge $cwarnth -AND $percentFree -lt $clowth) { $status =
"Low"
} Else { $status =
"Good"
#Prepare the output with a custom object
$mydisk +=New-Object PSObject -Property @{
Server=$_.Server
DeviceID= $disk.DeviceID
VolumeName= $disk.VolumeName
Size= [math]::Round(($disk.Size /
GB),
Freespace= [math]::Round((($disk.Size - $disk.FreeSpace)/
Percentage= (
"{0:P}"
-f ($disk.FreeSpace / $disk.Size))
status=$status
27.
# The
below
code
is used to preserve the order in the csv file
28.
$mydisk |Select-Object @{Name=
"Server"
;Expression={$_.Server}},@{Name=
"DeviceID"
;Expression={$_.DeviceID}},
29.
@{Name=
"VolumeName"
;Expression={$_.VolumeName}},
30.
"Size"
;Expression={$_.Size}},
31.
"FreeSpace"
;Expression={$_.FreeSpace}},
32.
"% Free"
;Expression={$_.Percentage}},
33.
"Status"
;Expression={$_.status}}|Export-Csv $Filename -NoTypeInformation
34.
#>
35.
36.
$mydisk |Export-Csv $Filename -NoTypeInformation
The issue with an output formatting i.e. is to ensure the output of an object to be displayed in a certain order because PoSH rearranges the output as per available metadata.
Line #18
By default, the columns are ordered depending on the available internal data. We can expect the order the output column.
Line #19
Manually forcing the output to maintain the order by creating a hash table, so that properties stay in the order as they were declared
#Creating PowerShell custom objects
$Mydisk=@()
_LogicalDisk -ComputerName <
computername
> | where {$_.driveType -eq
$mydisk |format-table -AutoSize
$mydisk |Format-Table Server,DeviceID,VolumeName,Size,FreeSpace,Percentage -AutoSize
Line #22
Control the order of the columns using width and alignment
_LogicalDisk -ComputerName hqdbsp
| where {$_.driveType -eq
<#
.SYNOPSIS
Name : Disk Space Utilization Report (Get-DiskSpaceExcel.ps
Description : Get disk space usage information from remote server(s) with WMI and output CSV file
Author : Prashanth Jayaram
* Select list of servers from a CSV file
* Get remote Servers informations with WMI and Powershell
* Disk (Disk type, letter, capacity in GB, free space in GB, % free , Status + display a CSV output)
* Log the details in activity log file
.INPUT
.csv file with servers to activate
.OUTPUTS
Console outputs : You can alter the
to write the data to file or console
.NOTES
Version:
1.0
Author: Prashanth Jayaram
Creation Date:
2016
-10
-05
Purpose/Change: Initial script development
.\Get-DiskSpaceCSV.ps
#########################################################################################
#### Input CSV, output CSV File, Log file Location
param (
[Parameter(Mandatory=$true)][string]$inputFile,
[Parameter(Mandatory=$true)][string]$DirectorytoSave
#Assign arguments to variables
$InputCSV=$inputFile
$DirectoryToSaveTo = $DirectorytoSave
# formatting the date
# before we do anything else, are we likely to be able to save the file?
# if the directory doesn't exist, then create it
if (!(Test-Path -path
"$DirectoryToSaveTo"
)) #create it if not existing
New-Item
-type directory | out-null
# Check if the output file CSV exist, if exists then delete it.
$filename =
"$DirectoryToSaveTo$filename.csv"
if (test-path $filename ) { rm $filename }
# check the existence of log file, If the log file doesn't exist, then create it
$logfile =
"$DirectoryToSaveTo$LogFileName.log"
"$logfile"
New-Item -ItemType file $logfile -Force
# Prepare headers for the log file for each execution of script
Add-Content $logfile
"#################################################################"
"Disk Space Details"
"Generated $(get-date)"
"Generated from $(gc env:computername)"
.Synopsis
Write-Log writes a message to a specified log file along with the current time stamp also writes state of the message.
.DESCRIPTION
The Write-Log function is designed to add logging capability to other scripts.
In addition to writing output and/or verbose you can write to a log file for
later debugging.
Created by: Prashanth Jayaram
.PARAMETER Message
Message is the content that you wish to add to the log file.
.PARAMETER Level
Specify the criticality of the log information being written to the log (i.e. Error, Warning, Informational)
.PARAMETER logfile
The path to the log file to which you would like to write. By
default
the function will create the path and file if it does not exist.
#Import the file to get the drives status and other usage details
Import-Csv $inputCSV|%{
$cserver = $_.Server
$cdrivelt = $_.Drive
$clowth = $_.LowTh
$cwarnth = $_.WarnTh
$ccritth = $_.CritTh
If (!(Test-Connection $_.Server -count
-quiet)) {
#Write the message to the log file
Write-Log -
ERROR -Message
"$($_.Server) is not reachable"
-Logfile $Logfile
else
#Write the Progress to log file
Write-Log -Message
"$($_.Server) is reachable and starting the process "
<# The
invoke-item $Filename