Not sure how to explain this, we're doing an assessment on disk usage on Azure, to reduce costs. We are trying to asses the space on each vm and reduce the disks
I'd like to add a recommendation column in there based on the free space, if the freespace is greater than 90% then add a comment "consider resizing" if less than 15% then "consider disk clean up".
The script I have works fine except it doesn't add the comment in, first I tried this...
$computers = (Get-AdComputer -Filter "name -like 'VM-*'").Name | Sort-Object
foreach ($computer in $Computers)
{
$vol = gwmi Win32_volume -Computer $Computer -Filter 'DriveType = 3'
#$vol
$info = $vol | select PsComputerName, DriveLetter, Label,
#{n='Capacity';e={[int]($_.capacity/1GB)}},
#{n='FreeSpace';e={[int]($_.FreeSpace/1GB)}},
#{n='FreeSpace (%)';e={[int](($_.FreeSpace) / ($_.capacity) * 100.0)}}
if ('FreeSpace (%)' -gt 85)
{
Write-Output "Disk Usage Low, Consider Resizing Options"
}
else
{
Write-Output "Disk Usage High"
}
$info | Export-Csv "c:\temp\tempfiles\question.csv" -Append
}
That didn't work, I then tried adding another section, where I get true or false, which seems to work.. that one is below, however I need to dd recommendations in..
$computers = (Get-AdComputer -Filter "name -like 'VM-*'").Name | Sort-Object
foreach ($computer in $Computers)
{
$vol = gwmi Win32_volume -Computer $Computer -Filter 'DriveType = 3'
#$vol
$info = $vol | select PsComputerName, DriveLetter, Label,
#{n='Capacity';e={[int]($_.capacity/1GB)}},
#{n='FreeSpace';e={[int]($_.FreeSpace/1GB)}},
#{n='FreeSpace (%)';e={[int](($_.FreeSpace) / ($_.capacity) * 100.0)}},
#{n='Recommendation';e={[String] ($_.FreeSpace -gt 90)}}
$info | Export-Csv "c:\temp\tempfiles\question.csv" -Append
}
Hope that makes sense.
Thanks in advance :)
The e stands for Expression. So you should be able to use an expression in there, using the original object properties (i.e. not your custom property names such as FreeSpace (%))
$computers = (Get-AdComputer -Filter "name -like 'VM-*'").Name | Sort-Object
foreach ($computer in $Computers)
{
$vol = gwmi Win32_volume -Computer $Computer -Filter 'DriveType = 3'
#$vol
$info = $vol | select PsComputerName, DriveLetter, Label,
#{n='Capacity';e={[int]($_.capacity/1GB)}},
#{n='FreeSpace';e={[int]($_.FreeSpace/1GB)}},
#{n='FreeSpace (%)';e={[int](($_.FreeSpace) / ($_.capacity) * 100.0)}},
#{n='Recommendation';e={
if((($_.FreeSpace) / ($_.capacity) * 100.0) -gt 90){
"Disk Usage Low, Consider Resizing Options"
}elseif((($_.FreeSpace) / ($_.capacity) * 100.0) -gt 75){
"Something else"
}else{
"Disk Usage High"
}
}
$info | Export-Csv "c:\temp\tempfiles\question.csv" -Append
}
Related
Need some assistance with the below script created, i can create a HTML report of the disk space for all remote machines i specified; however how do i add a meaningful description for each host i.e the pic below.
Script below
$Machine = #("Fakehost1", "Fakehost2", "fakehost3")
Get-CimInstance Win32_LogicalDisk -ComputerName $Machine -Filter "DriveType = '3'" -ErrorAction SilentlyContinue |
Select-Object PsComputerName, DeviceID,
#{N="Disk Size (GB) "; e={[math]::Round($($_.Size) / 1073741824,0)}},
#{N="Free Space (GB)"; e={[math]::Round($($_.FreeSpace) / 1073741824,0)}},
#{N="Free Space (%)"; e={[math]::Round($($_.FreeSpace) / $_.Size * 100,1)}} |
Sort-Object -Property 'Free Space (%)' |
ConvertTo-Html -Head $Head -Title "$Title" -PreContent "<p><font size=`"6`">$Title</font><p>Generated on $date</font></p>" > $HTML
A quick fix is to Sruce up the PSComputerName object in the same Select-Object command. You're already doing a lot of calculated properties what's 1 more...
Get-CimInstance Win32_LogicalDisk -ComputerName $Machine -Filter "DriveType = '3'" -ErrorAction SilentlyContinue |
Select-Object #{N = 'PSComputerName'; E = { $_.PSComputerName + " : Description" }},
DeviceID,
#{N="Disk Size (GB) ";e={[math]::Round($($_.Size) / 1073741824,0)}},
#{N="Free Space (GB)";e={[math]::Round($($_.FreeSpace) / 1073741824,0)}},
#{N="Free Space (%)";e={[math]::Round($($_.FreeSpace) / $_.Size * 100,1)}} |
Sort-Object -Property 'Free Space (%)' |
ConvertTo-Html -Head $Head -Title "$Title" -PreContent "<p><font size=`"6`">$Title</font><p>Generated on $date</font></p>" > $HTML
This tested good in my environment, but you will have to decide how to or what the actual description should be... If you are in an AD environment maybe you can create a hash to hold the descriptions like:
$Descriptions = #{}
$Machine |
Get-ADComputer -Properties Description |
ForEach-Object{ $Descriptions.Add( $_.Name, $_.Description ) }
Then change the PSComputerName expression like:
#{N = 'PSComputerName'; E = { $_.PSComputerName + $Descriptions[$_.PSComputerName] }}
This would reference the hash and return the value you got from the AD description attribute. Of course, that means the attribute has to be populated. But it's just 1 idea to demonstrate the point that the description must be mined from somewhere.
Update:
To answer your comment, You could manually specify the hash instead. use something like below, before the Get-CimInstance command. Make sure to remove the previous AD stuff...
$Descriptions =
#{
Fakehost1 = "SQL Server for some bug app..."
Fakehost2 = "File Server 1"
Fakehost3 = "Another file server"
}
$computers = Get-Content -Path c:\server\computers.txt
$computers | foreach {
$os = Get-WmiObject win32_OperatingSystem -computername $_
Get-WMIObject Win32_Logicaldisk -filter "deviceid='$($os.systemdrive)'" -ComputerName $_
} | Select PSComputername,DeviceID,
#{Name="SizeGB";Expression={$_.Size/1GB -as [int]}},
#{Name="FreeGB";Expression={[math]::Round($_.Freespace/1GB,2)}} |
Sort FreeGB | Format-Table -Autosize >> C:\server\diskreport.txt
Since there really was no question posted or errors given for what you have, here's what I use to get the disk space on a server. You can always get a list and throw it into a foreach loop sending them to this function and throw the output to a file however you would like.
Function Get-DiskInventory
{
[CmdletBinding()]
Param (
[Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)]
[alias("Name")]
[string[]]$ComputerName="localhost",
[validateset(2,3)]
[int]$DriveType=3,
[Parameter()]
[string]$DriveLetter
)
Begin{
Write-Verbose "Getting disk inventory on $ComputerName"
}
Process {
foreach ($Computer in $ComputerName) {
Write-Verbose "Connecting to $Computer"
Write-Verbose "Looking for drive type $DriveType"
$Result = Get-WmiObject -Class win32_logicaldisk -ComputerName $Computer -Filter "drivetype=$DriveType" |
Select-Object -Property #{label='Computer';expression={$Computer}},
DeviceID,
#{label='Size(GB)';expression={$_.Size / 1GB -as [int]}},
#{label='UsedSpace(GB)';expression={($_.Size - $_.FreeSpace) / 1GB -as [int]}},
#{label='FreeSpace(GB)';expression={$_.FreeSpace / 1GB -as [int]}},
#{label='%Free';expression={$_.FreeSpace / $_.Size * 100 -as [int]}}
if ($DriveLetter) {
Write-Verbose "Filtering drives"
$Result = $Result | where deviceid -EQ "$DriveLetter`:"
}
$Result | Select-Object -Property * -Unique
}
}
End{
Write-Verbose "Finished running command"
}
}
This question already has an answer here:
Converting from bytes into gigabytes
(1 answer)
Closed 5 years ago.
I have been working on this script to capture disk sizes, however I have them in bytes and they're messy, I have looked at several ways to add a decimal point, but I'm having trouble converting to GB first, Also alongside disk sizes I am trying to calculate free disk size and percentage used.
$servers = (Get-AdComputer -Filter "name -like MY-VM-*'").Name | Sort-Object
foreach ($Server in $Servers)
{
$disks= get-wmiobject -ComputerName $Server Win32_volume | select-object pscomputername, Capacity, driveletter, freespace |`
format-table | out-file c:\temp\new3.txt -append
Foreach ($disk in $disks)
{
$driveletter = $disk.driveletter
$totalsize = $disk.capacity
$freespace = $disk.freespace
$freespace = [math]::round($freespace[$_] /9.3132257461548)
$Percent_Free = [math]::round(($freespace / $totalsize ) * 100)
}
}
Hope that makes sense :)
Your query has already been answered in the comment. You can directly do this -
$servers = (Get-AdComputer -Filter "name -like MY-VM-*'").Name | Sort-Object
foreach ($Server in $Servers)
{
$disks= get-wmiobject -ComputerName $Server Win32_volume | select-object pscomputername, Capacity, driveletter, freespace |`
format-table | out-file c:\temp\new3.txt -append
Foreach ($disk in $disks)
{
$driveletter = $disk.driveletter
$totalsize = $disk.capacity/1GB
$freespace = $disk.freespace/1GB
$Percent_Free = [math]::round(($freespace / $totalsize ) * 100)
}
}
This question already has answers here:
Change order of columns in the object
(5 answers)
Closed 5 years ago.
Good Afternoon,
I have the following script to generate a table as part of a html report that I have:
(import-csv "C:\AutoTasks\server.txt" |
% {new-object psobject -property #{
"Asset Number"=$_.Computer;
"Region"=$_.Description;
"Online Status"=(test-connection -computername $_.Computer -quiet -count 1);
"Online Since"= Try {(([Management.ManagementDateTimeConverter]::ToDateTime((gwmi Win32_OperatingSystem -ComputerName $_.Computer -ErrorAction Stop).LastBootUpTime)))} Catch {"Offline"} ;
"Service"=((Get-Service -ComputerName $_.Computer | Where-Object {$_.DisplayName -eq "ServiceName"}).Status);
"Disk Size (GB)" = ([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).size)/1Gb,2));
"Free Disk Space (GB)" = ([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).freespace)/1Gb,2));
"Free Disk Space %" = ([Math]::Round(100*(([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).freespace)/1Gb,2)) / ([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).size)/1Gb,2))),2))
}} | ConvertTo-HTML -as Table -Fragment -PreContent "<h2>Backup Machines</h2>" | Out-String)
It does everything I need.
However, my issue is with the column ordering. It doesn't display in the column order I've listed, and there is seemingly no logic behind the order it offers.
Any ideas how I can specify the order, am I missing a format-table statement somewhere? My searches are drawing a blank.
In PowerShell 3.0 and newer, you can use the [ordered] attribute on a hashtable literal to indicate that you want an ordered dictionary instead:
(import-csv "C:\AutoTasks\server.txt" |
% {new-object psobject -property $([ordered]#{
"Asset Number"=$_.Computer;
"Region"=$_.Description;
"Online Status"=(test-connection -computername $_.Computer -quiet -count 1);
"Online Since"= Try {(([Management.ManagementDateTimeConverter]::ToDateTime((gwmi Win32_OperatingSystem -ComputerName $_.Computer -ErrorAction Stop).LastBootUpTime)))} Catch {"Offline"} ;
"Service"=((Get-Service -ComputerName $_.Computer | Where-Object {$_.DisplayName -eq "ServiceName"}).Status);
"Disk Size (GB)" = ([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).size)/1Gb,2));
"Free Disk Space (GB)" = ([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).freespace)/1Gb,2));
"Free Disk Space %" = ([Math]::Round(100*(([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).freespace)/1Gb,2)) / ([Math]::Round(((get-WmiObject win32_logicaldisk -Computername $_.Computer -Filter $_.Drive).size)/1Gb,2))),2))
})} | ConvertTo-HTML -as Table -Fragment -PreContent "<h2>Backup Machines</h2>" | Out-String)
recently I took it upon myself to learn Powershell. It was a rough 2 weeks and a lot of reading but I'm getting better and better. I had some pressure at work to help with correcting our CMDB. We are about 7 months away from having a true Depolyment/Asset Management system in place. We have many reasons for relying on Powershell right now and we're trying to clean up a mess before we get the management system in. Anyway, I created a script that gets a lot of information for us. We have about 3000 objects/pcs and we need as much info as possible. Anyway, I created a script. So far it works well but I wanted some opinions from the experts or any advice. I feel like I did a decent job putting this together with only 2 weeks experiance but I really want to know what others think.
One thing I noticed: Windows 7 Boxes with IE9 and Up do not return a value for IE Version. Anyone know why?
Please see my code below:
Set-QADPSSnapinSettings -defaultSizeLimit 0
$FullPCList = (Get-QADComputer -SearchRoot $ou | Sort Name | select -expand name)
foreach ($computer in $FullPCList) {
ping -n 2 $computer >$null
if($lastexitcode -eq 0) { $Online = "Yes" } else { $Online = "No" }
$PCInfo = (Get-WmiObject -ComputerName $computer -Class Win32_ComputerSystem -ErrorAction SilentlyContinue)
$WinInfo = (Get-WmiObject -ComputerName $computer -Class Win32_OperatingSystem -ErrorAction SilentlyContinue)
$ram = ((Get-WmiObject -ComputerName $computer -Class Win32_PhysicalMemory -ErrorAction SilentlyContinue | Measure-Object Capacity -Sum).Sum / 1MB)
$bios = (Get-WmiObject -ComputerName $computer -Class Win32_Bios -ErrorAction SilentlyContinue)
$ie = (Get-Wmiobject -ComputerName $computer -namespace “root\CIMV2\Applications\MicrosoftIE” -query “select version from MicrosoftIE_Summary” -ErrorAction SilentlyContinue)
$freespace = ((Get-WmiObject -ComputerName $computer -Class Win32_LogicalDisk | Select Freespace | Measure-object Freespace -Sum).Sum / 1GB)
#Start uptime check
$LastBootUpTime = $WinInfo.ConvertToDateTime($WinInfo.LastBootUpTime)
$Time = (Get-Date) - $LastBootUpTime
$formattime = '{0:00}:{1:00}:{2:00}' -f $Time.Days, $Time.Hours, $Time.Minutes
#End Uptime Check
if ($WinInfo.Caption -match "Windows 7") {
$name = (Get-ChildItem -Path "\\$Computer\C$\Users" -Exclude "*Service*","*admin*","*Public*","*ffodero*","*jgalli*","*jwalters*","*frochet*" | Sort-Object LastAccessTime -Descending | Select-Object Name -First 1).Name
$loggedintime = (Get-ChildItem -Path "\\$Computer\C$\Users" -Exclude "*Service*","*admin*","*Public*","*ffodero*","*jgalli*" | Sort-Object LastAccessTime -Descending | Select-Object LastAccessTime -First 1).LastAccessTime
}
if ($WinInfo.Caption -match "Windows XP") {
$name = (Get-ChildItem -Path "\\$Computer\C$\Documents and Settings" -Exclude "*Service*","*admin*","*Public*" | Sort-Object LastAccessTime -Descending | Select-Object Name -First 1).Name
$loggedintime = (Get-ChildItem -Path "\\$Computer\C$\Documents and Settings" -Exclude "*Service*","*admin*","*Public*" | Sort-Object LastAccessTime -Descending | Select-Object LastAccessTime -First 1).LastAccessTime
}
$table = #{
Model = $PCInfo.Model
IEVersion = $ie.Version
Serial = $Bios.SerialNumber
Memory = $ram
DriveFreeSpaceGB = $freespace
Manufacturer = $PCInfo.Manufacturer
OSName = $WinInfo.Caption
Computer = $computer
Uptime = $formattime
LastloggedinUser = $name
LastLoggedinDate = $loggedintime
LoggedOnDuringScan = $PCInfo.Username
ServicePack = $WinInfo.ServicePackMajorVersion
Online = $Online
}
New-Object PSObject -Property $table | Export-Csv C:\logs\mother.csv -NoTypeInformation -Append
}
The namespace root\CIMV2\Applications\MicrosoftIE has been removed starting with Windows Vista (see note at the end of the blog post). You should be able to read the version number from the registry, though:
$hive = [UInt32]'0x80000002'
$key = 'SOFTWARE\Microsoft\Internet Explorer'
$reg = [WMIClass]"\\$computer\root\default:StdRegProv"
$ieVersion = $reg.GetStringValue($hive, $key, 'Version').sValue