#Requires -version 2.0 #Get-DiskQuota-v2.ps1 # Jeffery Hicks # http://jdhitsolutions.com/blog # follow on Twitter: http://twitter.com/JeffHicks # "Those who forget to script are doomed to repeat their work." # **************************************************************** # * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED * # * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF * # * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, * # * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. * # **************************************************************** Function Get-DiskQuota { #Requires -version 2.0 <# .Synopsis Retrieve quota usage information. .Description This function connects to the specified computer, default is the localhost, and returns quota usage information. Quota information will NOT be returned for the Domain Admins group or the Administrator account. It will also exclude entries without a quota limit. Quota information for all volumes is returned by default. Otherwise you can filter by volume, by user or by volume and user. The Domain parameter is used to more accurately define the user account. If you want to filter by domain alone, then run the function without any user filtering and pipe it to Where-Object where you can filter by the domain name. This function uses WMI so you must have RPC connectivity and appropriate credentials. You do not need PowerShell installed on the remote computer. .Parameter Computername The name of the computer to query. .Parameter Volume Return quota information for a specific volume on the remote server such as E:. .Parameter Username Return quota information for a specific user. Use the SAMAccountname. .Parameter Domain The NETBIOS domain name of the user account you are querying. The default is the domain of the current user running the function. .Parameter Credential A PSCredential object to use for alternate credential authentication. This must be a previously created object. .Example PS C:\> get-diskquota server02 Get quota usage for all users on all volumes on SERVER02. .Example PS C:\> get-diskquota server01 -volume F: -cred $admin In this example, quota information for all users on volume F: is returned. The query is made using alternate credentials, previously saved as $admin. .Example PS C:\> get-diskquota "File01","File02" -user jfrost -domain MyCompany Query servers File01 and File02 for all quota entries for user mycompany\jfrost on all volumes. .Example PS C:\> get-content servers.txt | get-diskquota -user Jhicks | Export-csv jhicks-quota.csv This example will take every server name in servers.txt and pipe it to the Get-Diskquota function which searches all volumes for the jhicks user account. The quota usage information is then piped to a CSV file using Export-CSV. .Inputs Accepts strings as pipelined input .Outputs A custom object with quota entry information .Link http://jdhitsolutions.com/blog/2009/11/get-disk-quota/ .Link Get-WmiObject .Notes NAME: Get-DiskQuota VERSION: 1.0 AUTHOR: Jeffery Hicks LASTEDIT: 11/18/2009 #> [CmdletBinding()] Param ( [Parameter( ValueFromPipeline=$True, Position=0, Mandatory=$False, HelpMessage="The computername to query")] [string[]]$Computername=$env:computername, [Parameter( ValueFromPipeline=$False,Mandatory=$False, HelpMessage="The volume name on the remote server. Use a value like E:.")] [string]$Volume, [Parameter( ValueFromPipeline=$False,Mandatory=$False, HelpMessage="The samAccountname of a user such as JDOE")] [string]$Username, [Parameter( ValueFromPipeline=$False,Mandatory=$False, HelpMessage="The domain name of the queried user such as MyCompany")] [string]$Domain=$env:Userdomain, [Parameter( ValueFromPipeline=$False, Mandatory=$False, HelpMessage="A previously created PSCredential object.")] [Parameter(ParameterSetName="Set2")] [management.automation.pscredential]$credential ) BEGIN { Write-Verbose "Starting function" if ($Username) { Write-Verbose "Looking for entries for $domain\$username"} #only retrieve quota entries that are limited $query="Select * from win32_diskquota where limit < 18446744073709551615" if ($Volume -AND $Username) { Write-Verbose "Building volume and username query" $query=$query + " AND QuotaVolume=""Win32_LogicalDisk.DeviceID='$volume'"" AND User =""Win32_Account.Domain='$domain',Name='$Username'""" } elseif ($Volume) { Write-Verbose "Building volume query" $query=$query + " AND QuotaVolume=""Win32_LogicalDisk.DeviceID='$volume'""" } elseif ($Username) { Write-Verbose "Building username query" $query=$query + " AND User =""Win32_Account.Domain='$domain',Name='$Username'""" } else { Write-Verbose "Getting all quota entries" } Write-Verbose "Query = $query" } #end BEGIN PROCESS { $Computername | foreach { #define an error handling trap in the same scope Trap { Write-Warning "There was an exception retrieving quota information from $computer)" Write-Warning $_.Exception.Message #bail out Return } $computer=$_.ToUpper() Write-Verbose "Querying $computer" if ($credential) { $quotas=get-wmiobject -query $query -computer $computer -Credential $credential -ea Stop } else { $quotas=get-wmiobject -query $query -computer $computer -ea Stop } #get quota entries and filter off local user accounts, administrator and domain admins $entries = $quotas | where {$_.user -notmatch "$computer|Administrator|Domain Admins"} if ($entries) { Write-Verbose "Found $($entries.count) entries" foreach ($entry in $entries) { Write-Verbose "Processing entry" #remove quotes from user property and split the user entry at the comma #assuming no commas in the domain or username $replaced=($entry.user).Replace('"',"") Write-Verbose "`$replace = $replaced" $userdata=$replaced.split(",") #item 0 will be the domain and item 1 will be the user. Each item needs #to be further split. The domain and username values should be the same as any #values passed as paramters. I'll override the default domain parameter value. #Otherwise, if it isn't specified and the admin running the script isn't in the domain #you'll get the wrong domain listed. $domain=$userdata[0].Split("=")[1] $username=$userdata[1].Split("=")[1] Write-Verbose "Parsed out $domain and $username" #parse QuotaVolume and strip off quotes $Volume=($entry.quotavolume.split("=")[1]).Replace('"',"") $Volume=$Volume.ToUpper() Write-Verbose "`$volume=$volume" #calculate % of quota used $percentUsed="{0:P2}" -f ([double]$entry.DiskSpaceUsed/[double]$entry.Limit) Write-Verbose "`$percentused = $percentused" #calculate limit remaining space [double]$limitRemaining="{0:N2}" -f (([double]$entry.limit - [double]$entry.DiskSpaceUsed)/1GB) Write-Verbose "`$limitRemaining = $limitRemaining" #is user over the warning limit? if ($entry.diskspaceused -gt $entry.WarningLimit) { $Warning=$True } else { $Warning=$False } Write-Verbose "`$Warning=$warning" #is user over the hard limit? if ($entry.diskspaceused -gt $entry.Limit) { $OverLimit=$True } else { $OverLimit=$False } Write-Verbose "`$overlimit=$overlimit" Write-Verbose "Creating blank object" #create a blank object $obj = New-Object PSObject Write-Verbose "Adding properties to the object" #add some properties to the object $obj | Add-Member -membertype NoteProperty -Name Volume -Value $Volume $obj | Add-Member -membertype NoteProperty -Name Computername -Value $computer $obj | Add-Member -membertype NoteProperty -Name Username -Value "$domain\$username" $obj | Add-Member -membertype NoteProperty -Name UsedSpaceMB -Value (($entry.DiskSpaceUsed/1MB) -as [double]) $obj | Add-Member -membertype NoteProperty -Name PercentUsed -Value $percentUsed $obj | Add-Member -membertype NoteProperty -Name LimitGB -Value (($entry.Limit/1GB) -as [int]) $obj | Add-Member -membertype NoteProperty -Name LimitRemainingGB -Value $limitRemaining $obj | Add-Member -membertype NoteProperty -Name WarningGB -Value (($entry.WarningLimit/1GB) -as [int]) $obj | Add-Member -membertype NoteProperty -Name OverWarning -Value $Warning $obj | Add-Member -membertype NoteProperty -Name OverLimit -Value $OverLimit #write object to the pipeline Write-Verbose "Writing the object to the pipeline" write $obj } #end ForEach } #end if else { Write-Warning "No quota entries found that match your query on $computer" Write-Warning $query } } #end ForEach Computername } #end PROCESS END { Write-Verbose "Exiting function" } #end END } #end Function Set-Alias gdq Get-DiskQuota #end Script # help gdq