SSR-IS
asked on
Powershell script to get size of shares and freespace of volume
I´m trying to build a powershell script, but I have definitely not enough know how about it. So maybe someone could help me with this or provide some information. What I want the script to do is the following:
I have an input-file with UNC-pathes to network shares on different servers. The script should use this file to get me the foldersize of the shares and also provide information about the freespace of the volume where the share exists.
An output like UNC - local Volume - total size - free space - sharesize would be perfect.
I´ve read and testet some scripts which I found here, but I can not get this to work...
At least this has not to be solved with powershell. If someone has a solution in VBS it would be fine also.
Any help would be welcome!
Regards
Steffen
I have an input-file with UNC-pathes to network shares on different servers. The script should use this file to get me the foldersize of the shares and also provide information about the freespace of the volume where the share exists.
An output like UNC - local Volume - total size - free space - sharesize would be perfect.
I´ve read and testet some scripts which I found here, but I can not get this to work...
At least this has not to be solved with powershell. If someone has a solution in VBS it would be fine also.
Any help would be welcome!
Regards
Steffen
can u post an example pf how the unc and shared folder is listed in the file?
ASKER
Oh, at least it doesn´t matter how the input file should look like. The easiest for would be
\\server1\share1
\\server1\share2
\\server2\share1
...
But I could also provide an input-file without the backslashes...
\\server1\share1
\\server1\share2
\\server2\share1
...
But I could also provide an input-file without the backslashes...
the script reads from UNC_LIST_FILE (modify it in the script) and expect unc in the format you posted.
for example:
\\s004\temp
the output result is csv, for example:
UNC,FolderPath,FolderSize, DriveSize, DriveFreeS pace
s004,C:\temp,675.421240806 58,152624. 99609375,1 01631.9257 8125
all sizes are in MB.
for example:
\\s004\temp
the output result is csv, for example:
UNC,FolderPath,FolderSize,
s004,C:\temp,675.421240806
all sizes are in MB.
const UNC_LIST_FILE = "c:\temp\shared_volume.txt"
const LOG_FILE = "c:\temp\output.log"
set objFSO = createobject("scripting.filesystemobject")
set objFile = objFSO.OpenTextFile(UNC_LIST_FILE, 1)
arrVolumes = Split(objFile.ReadAll, vbNewLine)
objFile.Close
set objLogFile = objFSO.CreateTextFile(LOG_FILE, 1)
objLogFile.WriteLine "UNC,FolderPath,FolderSize,DriveSize,DriveFreeSpace"
for each vol in arrVolumes
Set objFolder = objFSO.GetFolder(vol)
folderSize = (objFolder.Size/1048576)
tokens = Split(vol, "\")
name = tokens(UBound(tokens))
server = tokens(UBound(tokens)-1)
strLogLine = server
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & server & "\root\cimv2")
Set colShares = objWMIService.ExecQuery("Select Path from Win32_Share where name = '" & name & "'")
For each objShare in colShares
strLogLine = strLogLine & "," & objShare.Path
drive = Split(objShare.Path,":")(0)
exit for
Next
strLogLine = strLogLine & "," & folderSize
Set objWMIService = GetObject("winmgmts:\\" & server & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select FreeSpace,Size from Win32_LogicalDisk where Name='" & drive & ":'")
For Each objItem in colItems
size = (objItem.Size/1048576)
freeSpace = (objItem.FreeSpace/1048576)
strLogLine = strLogLine & "," & size
strLogLine = strLogLine & "," & freeSpace
exit for
next
objLogFile.WriteLine strLogLine
next
objLogFile.Close
wscript.echo "Done"
ASKER
Thanks a lot, sedgwick! Yout Script runs really perfect for me!
Do you mind me asking you three more things?
Could we get the sizes in GB?
Could we get the output values seperated by semikolon instead of komma?
And another thing: Would it be a lot of work to get the results in an excel worksheet? Eventually written "live"? - But don´t spent to much time on this, I could even also import it there...
Regards
Steffen
Do you mind me asking you three more things?
Could we get the sizes in GB?
Could we get the output values seperated by semikolon instead of komma?
And another thing: Would it be a lot of work to get the results in an excel worksheet? Eventually written "live"? - But don´t spent to much time on this, I could even also import it there...
Regards
Steffen
now the script logs GB sizes, and use semikolon instead of comma.
regarding excel, it's gonna take sometime if you can wait...
regarding excel, it's gonna take sometime if you can wait...
const UNC_LIST_FILE = "c:\temp\shared_volume.txt"
const LOG_FILE = "c:\temp\output.log"
set objFSO = createobject("scripting.filesystemobject")
set objFile = objFSO.OpenTextFile(UNC_LIST_FILE, 1)
arrVolumes = Split(objFile.ReadAll, vbNewLine)
objFile.Close
set objLogFile = objFSO.CreateTextFile(LOG_FILE, 1)
objLogFile.WriteLine "UNC,FolderPath,FolderSize,DriveSize,DriveFreeSpace"
for each vol in arrVolumes
Set objFolder = objFSO.GetFolder(vol)
folderSize = (objFolder.Size/1073741824)
tokens = Split(vol, "\")
name = tokens(UBound(tokens))
server = tokens(UBound(tokens)-1)
strLogLine = server
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & server & "\root\cimv2")
Set colShares = objWMIService.ExecQuery("Select Path from Win32_Share where name = '" & name & "'")
For each objShare in colShares
strLogLine = strLogLine & ";" & objShare.Path
drive = Split(objShare.Path,":")(0)
exit for
Next
strLogLine = strLogLine & ";" & folderSize
Set objWMIService = GetObject("winmgmts:\\" & server & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select FreeSpace,Size from Win32_LogicalDisk where Name='" & drive & ":'")
For Each objItem in colItems
size = (objItem.Size/1073741824)
freeSpace = (objItem.FreeSpace/1073741824)
strLogLine = strLogLine & ";" & size
strLogLine = strLogLine & ";" & freeSpace
exit for
next
objLogFile.WriteLine strLogLine
next
objLogFile.Close
wscript.echo "Done"
ASKER
If it´s okay for you to do the coding I could wait a while!
here's output to excel.
const UNC_LIST_FILE = "c:\temp\shared_volume.txt"
const LOG_FILE = "c:\temp\output.log"
const OUTPUT_EXCEL_FILE = "c:\temp\Live.xlsx"
const SHEET_HEADERS = "UNC;FolderPath;FolderSize;DriveSize;DriveFreeSpace"
set objFSO = createobject("scripting.filesystemobject")
set objFile = objFSO.OpenTextFile(UNC_LIST_FILE, 1)
arrVolumes = Split(objFile.ReadAll, vbNewLine)
objFile.Close
Const xlExcel7 = 51
On Error Resume Next
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = false
If (Err.Number <> 0) Then
On Error GoTo 0
Wscript.Echo "Excel application not found."
Wscript.Quit
End If
On Error GoTo 0
col=1
row=2
' Create a new workbook.
objExcel.Workbooks.Add
' Bind to worksheet.
Set objSheet = objExcel.ActiveWorkbook.Worksheets(1)
for each header in Split(SHEET_HEADERS,";")
objSheet.Cells(1, col).Value = header
col=col+1
next
for each vol in arrVolumes
Set objFolder = objFSO.GetFolder(vol)
folderSize = (objFolder.Size/1073741824)
tokens = Split(vol, "\")
name = tokens(UBound(tokens))
server = tokens(UBound(tokens)-1)
path=""
size=""
freeSpace=""
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & server & "\root\cimv2")
Set colShares = objWMIService.ExecQuery("Select Path from Win32_Share where name = '" & name & "'")
For each objShare in colShares
path = objShare.Path
drive = Split(objShare.Path,":")(0)
exit for
Next
Set objWMIService = GetObject("winmgmts:\\" & server & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select FreeSpace,Size from Win32_LogicalDisk where Name='" & drive & ":'")
For Each objItem in colItems
size = (objItem.Size/1073741824)
freeSpace = (objItem.FreeSpace/1073741824)
exit for
next
objSheet.Cells(row, 1).Value = server
objSheet.Cells(row, 2).Value = path
objSheet.Cells(row, 3).Value = folderSize
objSheet.Cells(row, 4).Value = size
objSheet.Cells(row, 5).Value = freeSpace
row=row+1
next
objExcel.DisplayAlerts = False
objExcel.ActiveWorkbook.SaveAs OUTPUT_EXCEL_FILE, xlExcel7
objExcel.ActiveWorkbook.Close false
' Quit Excel.
objExcel.Application.Quit
Set objSheet = Nothing
Set objExcel = Nothing
Wscript.Echo "done."
Let's try this PowerShell solution. This is raw data, we can format it to any format you like.
$shares = get-content c:\sharelist.txt # "\\server1\share1", "\\server2\share2"
$shares | %{
if($_ -match "\\\\([^\\]+)\\(.+)$"){
$server = $matches[1]
$name = $Matches[2]
$wmi = Get-WmiObject -ComputerName $server -Class Win32_Share -Filter "name = '$name'"
$driveletter = if($wmi.path -match "^(\w:)"){$matches[1]}
$drive = Get-WmiObject -ComputerName $server -Class Win32_logicaldisk -Filter "DeviceID = '$driveletter'"
$sharesize = (Get-ChildItem $_ -Recurse -ErrorAction SilentlyContinue | ?{!$psiscontainer} | Measure-Object -Property length -Sum).sum
New-Object -TypeName PSObject -Property @{UNC = $_; volume = $driveletter; size= $drive.size; freespace = $drive.freespace; sharesize = $sharesize}
}
}
Just for fun... A PowerShell version.
All sizes are in Gb to two decimal places. Exports to a CSV file at the end, do yell if the comments aren't sufficient.
Chris
# Read the text file
Get-Content Test.txt | ForEach-Object {
# Get the server name
$Server = $_ -Replace '^\\\\|\\.*$'
# Get the share
$ShareName = $_ -Replace '^.*\\'
$Share = [WMI]"\\$Server\root\cimv2:Win32_Share.Name='$Sharename'"
# Get the disk
$VolumeDeviceID = $Share.Path -Replace '\\.*$'
$Volume = [WMI]"\\$Server\root\cimv2:Win32_LogicalDisk.DeviceID='$VolumeDeviceID'"
# Build the output combining everything we found above
"" | Select-Object `
@{n='ServerName';e={ $Server }},
@{n='ShareName';e={ $ShareName }},
@{n='Path';e={ $Share.Path }},
@{n='Volume';e={ $Volume.Name }},
@{n='TotalSize';e={ '{0:N2}' -f ($Volume.Size / 1Gb) }},
@{n='Freespace';e={ '{0:N2}' -f ($Volume.Freespace / 1Gb) }},
@{n='ShareSize';e={ '{0:N2}' -f ((Get-ChildItem $_ -Recurse | Measure-Object Length -Sum).Sum / 1Gb) }}
# Export the results to a CSV file
} | Export-Csv File.csv -NoTypeInformation
ASKER
Thanks a lot guys!
You´re posting faster as I can test the scripts. But I´ll let you know when I managed to do so...
You´re posting faster as I can test the scripts. But I´ll let you know when I managed to do so...
@Chris-Dent
i'm amazed everytime how many lines of code are required to perform a task in vbs as opposed to powershell.
i'm amazed everytime how many lines of code are required to perform a task in vbs as opposed to powershell.
ASKER
@Chris-Dent:
Something seems to be wrong with building ".sum". Please see my result:
"ServerName","ShareName"," Path","Vol ume","Tota lSize","Fr eespace"," ShareSize"
"server01","share01","D:\s hare01","D :","54,15" ,"9,58","0 ,01"
"server02","share01","I:\s hare01","I :","36,84" ,"32,68"," 0,01"
The ShareSize is the same value for both, but on the server the second share is about 3 GB.
Something seems to be wrong with building ".sum". Please see my result:
"ServerName","ShareName","
"server01","share01","D:\s
"server02","share01","I:\s
The ShareSize is the same value for both, but on the server the second share is about 3 GB.
Apologies, I broke it :)
Fixed here.
Chris
# Read the text file
Get-Content Test.txt | ForEach-Object {
# Get the server name
$Server = $_ -Replace '^\\\\|\\.*$'
# Get the share
$ShareName = $_ -Replace '^.*\\'
$Share = [WMI]"\\$Server\root\cimv2:Win32_Share.Name='$Sharename'"
# Get the disk
$VolumeDeviceID = $Share.Path -Replace '\\.*$'
$Volume = [WMI]"\\$Server\root\cimv2:Win32_LogicalDisk.DeviceID='$VolumeDeviceID'"
# Build the output combining everything we found above
$_ | Select-Object `
@{n='ServerName';e={ $Server }},
@{n='ShareName';e={ $ShareName }},
@{n='Path';e={ $Share.Path }},
@{n='Volume';e={ $Volume.Name }},
@{n='TotalSize';e={ '{0:N2}' -f ($Volume.Size / 1Gb) }},
@{n='Freespace';e={ '{0:N2}' -f ($Volume.Freespace / 1Gb) }},
@{n='ShareSize';e={ '{0:N2}' -f ((Get-ChildItem $_ -Recurse | Measure-Object Length -Sum).Sum / 1Gb) }}
# Export the results to a CSV file
} | Export-Csv File.csv -NoTypeInformation
ASKER
Okay, I´ll do some more testing, but for now I can say the following:
Sedgwick´s and Chris-Dent´s scripts are running both very smooth, with not a lot of differences if you want to work with the results in Excel.
It seems to me the the VBS-Solution runs a lot quicker than the powershell version:
VBS --> 6 seconds on the 3 GB testshare
PS --> 59 seconds on the 3 GB testshare
If I calculate this for 500 GB-shares.....
Sedgwick´s and Chris-Dent´s scripts are running both very smooth, with not a lot of differences if you want to work with the results in Excel.
It seems to me the the VBS-Solution runs a lot quicker than the powershell version:
VBS --> 6 seconds on the 3 GB testshare
PS --> 59 seconds on the 3 GB testshare
If I calculate this for 500 GB-shares.....
It's the bit that gets the folder size, we have to recurse down the folder structure if we use Get-ChildItem, counting all the files. We can use the same method as VbScript though.
You may find relatively small discrepancies in size, but it's worth a try :)
Chris
# Read the text file
Get-Content Test.txt | ForEach-Object {
# Get the server name
$Server = $_ -Replace '^\\\\|\\.*$'
# Get the share
$ShareName = $_ -Replace '^.*\\'
$Share = [WMI]"\\$Server\root\cimv2:Win32_Share.Name='$Sharename'"
# Get the disk
$VolumeDeviceID = $Share.Path -Replace '\\.*$'
$Volume = [WMI]"\\$Server\root\cimv2:Win32_LogicalDisk.DeviceID='$VolumeDeviceID'"
# Build the output combining everything we found above
$_ | Select-Object `
@{n='ServerName';e={ $Server }},
@{n='ShareName';e={ $ShareName }},
@{n='Path';e={ $Share.Path }},
@{n='Volume';e={ $Volume.Name }},
@{n='TotalSize';e={ '{0:N2}' -f ($Volume.Size / 1Gb) }},
@{n='Freespace';e={ '{0:N2}' -f ($Volume.Freespace / 1Gb) }},
@{n='ShareSize';e={ '{0:N2}' -f ((New-Object -ComObject Scripting.FileSystemObject).GetFolder($_).Size / 1Gb) }}
# Export the results to a CSV file
} | Export-Csv File.csv -NoTypeInformation
ASKER
I understand the changes you made to use filesystem object, but the funny thing ist, that now the powershell script runs faster then vbs.
Maybe I have the opportunity to test the scripts on our larger shares (30 to 800 GB) tomorrow morning.
Maybe I have the opportunity to test the scripts on our larger shares (30 to 800 GB) tomorrow morning.
Good, that's the way it should be ;)
It's quite likely that the WMI pieces are where you get the speed improvement. In the case of mine we're connecting directly to a WMI resource rather than searching for it.
Chris
ASKER
Okay, I did some testing this morning on our larger shares and everthing worked fine. If yout time allows, there one more thing which would make the script perfect:
Is it possible to implement some kind of status/ progress bar? The script will run for al long time and it would be nice to know if its still alive...
Steffen
Is it possible to implement some kind of status/ progress bar? The script will run for al long time and it would be nice to know if its still alive...
Steffen
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks again - works nice and does anything I need!
I guess I should learn some powershell stuff, there´s a lot of things which can be done very elegant.
Can you recommend some books or so to get a good entry point?
I guess I should learn some powershell stuff, there´s a lot of things which can be done very elegant.
Can you recommend some books or so to get a good entry point?
Yeah, this is a good starting point:
http://powershell.com/Mastering-PowerShell.pdf
Once you start getting through that you can explore some of the resources listed here:
http://social.technet.microsoft.com/wiki/contents/articles/windows-powershell-survival-guide.aspx
And these physical books are highly regarded:
PowerShell Cookbook - http://oreilly.com/catalog/9780596801519
PowerShell in Action - http://www.manning.com/payette/
They have different focus, if you're looking at administrative work the Cookbook may be the best bet (just make sure you get the new edition, 2nd edition).
Chris
http://powershell.com/Mastering-PowerShell.pdf
Once you start getting through that you can explore some of the resources listed here:
http://social.technet.microsoft.com/wiki/contents/articles/windows-powershell-survival-guide.aspx
And these physical books are highly regarded:
PowerShell Cookbook - http://oreilly.com/catalog/9780596801519
PowerShell in Action - http://www.manning.com/payette/
They have different focus, if you're looking at administrative work the Cookbook may be the best bet (just make sure you get the new edition, 2nd edition).
Chris
ASKER
So at least all my questions are answered and the results are great!
that's a whole new "project" and not really in this scope.
i've found something that create dynamically htmlfile object and update it but it needs major modification.
check http://www.computing.net/answers/programming/vbscript-show-progress/14186.html
i think you should open new question for it, i'd happily assist you if it wasn't like this.
sorry man.
i've found something that create dynamically htmlfile object and update it but it needs major modification.
check http://www.computing.net/answers/programming/vbscript-show-progress/14186.html
i think you should open new question for it, i'd happily assist you if it wasn't like this.
sorry man.
Hi, is it possible to modify the script just to type the server name only and then get all of the network shares recursively then pipe that output to the script above ?