Thursday, February 14, 2013

Monitoring Disk space using T-SQL and Powershell

Hello everybody,

Here is a handy script that allows you to get disks information using T-SQL and Powershell. It is useful to monitor the free space on each disk so we can create a sql job to run it periodically and send out a notification when space is getting low

Here is the script



USE master
GO
SET NOCOUNT ON
declare @svrName varchar(255)
declare @sql varchar(400)
--by default it will take the current server name, we can the set the server name as well
set @svrName = @@SERVERNAME
set @sql = 'powershell.exe -c "Get-WmiObject -ComputerName ' + QUOTENAME(@svrName,'''') + ' -Class Win32_Volume -Filter ''DriveType = 3'' | select name,capacity,freespace,Label | foreach{$_.name+''|''+$_.capacity/1048576+''%''+$_.freespace/1048576+''&''+$_.label+''*''}"'
--creating a temporary table
DECLARE @output TABLE
(line varchar(255))
--inserting disk name, total space and free space value in to temporary table
insert @output
EXEC xp_cmdshell @sql

DECLARE @DISKS TABLE(
id int identity
,[DiskName] varchar(10)
,[Capacity(MB)] bigint
,[FreeSpace(MB)] bigint
,[Label] varchar(200)
)

INSERT INTO @DISKS
select rtrim(ltrim(SUBSTRING(line,1,CHARINDEX('|',line) -1))) as drivename
      ,round(cast(rtrim(ltrim(SUBSTRING(line,CHARINDEX('|',line)+1,      (CHARINDEX('%',line) -1)-CHARINDEX('|',line)) )) as Float),0) as 'capacity(MB)'
      ,round(cast(rtrim(ltrim(SUBSTRING(line,CHARINDEX('%',line)+1,      (CHARINDEX('&',line) -1)-CHARINDEX('%',line)) )) as Float),0) as 'freespace(MB)'
      ,rtrim(ltrim(SUBSTRING(line,CHARINDEX('&',line)+1,      (CHARINDEX('*',line) -1)-CHARINDEX('&',line)) )) as 'Label'
from @output
where line like '[A-Z][:]%'
order by drivename


select *
,[Capacity(MB)]/1024 as [Capacity(GB)],[FreeSpace(MB)]/1024 as [FreeSpace(GB)]
,round( [FreeSpace(MB)]*100/[Capacity(MB)],2) as [% Free]
from @DISKS



7 comments:

  1. Hi Javier,

    I ran the above script on my lapton am getting only the columns no result set value. Please advise what to do? I need to enable any option in instance level.
    Thanks for your script.

    Redars,
    Raj

    ReplyDelete
  2. You need to check
    xp_cmdshell if it's enabled from sp_configure
    check if powershell it's installed. Try to execute the query directly in powershell.

    ReplyDelete
  3. Hi,
    The script above will only work on a default instance. If you are running a named instance @@servername returns the hostname \ instance name pair.

    If you use the value of
    SERVERPROPERTY ('ComputerNamePhysicalNetBIOS')

    or
    SERVERPROPERTY ('MachineName')

    will return the host machine name and allow the powershell part of the script to run correctly.

    You will have to Cast the output value of the function to varchar (255) as it is sql_variant data type.

    Have fun.
    Richard

    ReplyDelete
  4. xp_fixeddrives provides basically the same information in a easier way.

    ReplyDelete
  5. Hi,

    Can you tell me how can I configure the Jobs in SQL Server (using Management Studio) to run some scripts, sql scripts, sql statements, etc, and how can I configure the mail sending in SQL Server in way to receive the results of SQL jobs in my email address.

    Can you teach me that please?!

    Thank you,
    jmgmad

    ReplyDelete
  6. Anonymous, since you have such far reaching questions I would suggest you read the sql server books online for the various topics you are interested in.

    What you are asking is much more than would be doable in an online forum and is more something that you would hire a contractor to do for you.

    ReplyDelete
  7. Keeping tabs on available disk space on your SQL Servers is something that every DBA should do, because once SQL Server runs out of disk on the underlying host, then everything obviously comes to a crashing halt.

    ReplyDelete