Attempted to divide by 0

Hi, i am a beginner in powershell,
i am trying to create report for system Info following Don jones book - creating HTML reports, in this below function $props is created. How do i see the contents of the object $props

function Get-DiskInfo{
[CmdletBinding()]
param(
[Parameter(Mandatory=$True)][String]$ComputerName
)
$DI = Get-WmiObject -Class win32_LogicalDisk -ComputerName $computername
$props = @{ ‘VolumeName’=$DI.VolumeName;
‘Name’=$DI.Name;
‘Size(GB)’=“{0:n2}” -f ($DI.size/1GB);
‘AvailableSpace(GB)’=“{0:n2}” -f ($DI.freespace/1gb);
‘PercentFree(%)’=“{0:n2}” -f ($DI.freespace/$_.size*100);}
New-Object -TypeName PSObject -Property $props
}

Hi Sethuraman,
Typically you would just use $props to hold the data before passing them to the PSObject, and then output the PSObject

$obj = new-object -typename PSObject -property $props

Then you can display the object itself

$obj

Or send it down the pipeline

$obj | Do-Something

In other words, the contents of New-Object are the contents of $props.

If you wanted to validate $props first though, you can use $props by itself to display the contents.

Liam

Thanks liam,

in the previous function
$props = @{ ‘VolumeName’=$DI.VolumeName; —in this line i am getting error “Attempted to Divide by zero” as Runtime exception. Not sure why.

I think $props is essentially a single line of code as far as PowerShell is concerned.

I suspect the error is coming from

PercentFree(%)'="{0:n2}" -f ($DI.freespace/$_.size*100

$_ is syntax used in the pipeline. Since you aren’t in the pipeline it won’t work. Try changing $_.size to $DI.size

Thanks for pointing that out i missed to change that. but still i am getting the error.

FYI this is my whole piece of code

[CmdletBinding()]
param(
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True)]
[String]$ComputerName,
[Parameter(Mandatory=$True)]
[String]$Path
)

BEGIN{
Import-Module EnhancedHTML2
}

Process{

$Style =@"

body{
color:#333333;
font-family:calibri,Tahoma;
font-size : 10pt;
}

h1{
text-align:center;
}

h2{
border-top:1px solid #666666;
}

th{
font-weight:bold;
color:#eeeeee;
background-color:#333333
cursor:pointer;
}

.odd {background-color:#ffffff;}

.even {background-color:#dddddd;}

.paginate_enabled_next, .paginate_enabled_previous
{
cursor:pointer;
border:1px solid #222222;
background-color:#dddddd;
padding:2px;
margin:4px;
border-radius:2px
}

.paginate_disabled_previous, .paginate_disabled_previous
{
color:#666666;
cursor:pointer;
background-color:#dddddd;
padding:2px;
margin:4px;
border-radius:2px
}

.dataTables_info {margin-bottom:4px;}

.sectionheader {cursor:pointer;}

.secrtionheader:hover {color:red;}

.grid {width:100%}

.red{
color:red;
font-weight:bold;
}

"@

function Get-Disk{
[CmdletBinding()]
param(
[Parameter(Mandatory=$True)][String]$ComputerName
)
$DI = Get-WmiObject -Class win32_LogicalDisk -ComputerName $computername
$props = @{ ‘VolumeName’=$DI.Volumename;
‘Name’=$DI.Name;
‘Size’=“{0:n2}” -f ($DI.size/1GB);
‘AvailableSpace’=“{0:n2}” -f ($DI.freespace/1gb);
‘PercentFree’=“{0:n2}” -f ($DI.freespace/$DI.size*100);}
New-Object -TypeName PSObject -Property $props
}

foreach($computer in $ComputerName){
try{
$reachable = $true
Write-Verbose “Checking Connectivity to $computer”
Get-WmiObject -Class win32_bios -ComputerName $computer -EnableAllPrivileges Stop | Out-Null
}catch{
Write-Warning “$computer connectivity failed”
$reachable = $false
}
if($reachable){
$filepath = Join-Path -Path $Path -ChildPath “$computer.html”
}

    $params = @{'As'='Table';
                'Precontent'='♦ LocalDisks';
                'EvenRowCssClass'='even';
                'OddRowCssClass'='odd';
                'MakeTableDynamic'=$true;
                'TableCssClass'='grid';
                'Properties'='VolumeName','Name',
                @{n='Size(GB)';e={$_.Size}},
                @{n='AvailableSpace(GB)';e={$_.AvailableSpace};css={if($_.Percentfree -lt 80){'red'}}},
                @{n='PercentFree(%)';e={$_.PercentFree};css={if($_.Percentfree -lt 80){'red'}}}}
     $html_Disk = Get-Disk -ComputerName $computer | ConvertTo-EnhancedHTMLFragment @params
     
     $params = @{'CssStyleSheet'=$Style;
     'Title'="Disk Report for $computer";
     'PreContent'="Disk Report for $computer"
     'HTMLFragments'=@($html_Disk)}
     ConvertTo-EnhancedHTML @params | Out-File -FilePath $Path
    }

}

Definitely getting the same DivideByZero exception? Can you copy it in.
When I run the Get-Disk function that you have there. The Exception that I get is

Method invocation failed because [System.Object[]] does not contain a method named 'op_Division'. At line:7 char:5 + $props = @{ 'VolumeName'=$DI.Volumename; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (op_Division:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound

That’s because I have multiple disks, and so I need to loop over them with a foreach like this.

function Get-Disk {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory = $True)][String]$ComputerName
        )
        $DI = Get-WmiObject -Class win32_LogicalDisk -ComputerName $computername
        foreach ($i in $DI) {
            $props = @{ 'VolumeName' = $i.Volumename;
                'Name' = $i.Name;
                'Size' = "{0:n2}" -f ($i.size / 1GB);
                'AvailableSpace' = "{0:n2}" -f ($i.freespace / 1gb);
                'PercentFree' = "{0:n2}" -f ($i.freespace / $i.size * 100);
            }
            New-Object -TypeName PSObject -Property $props
        }
    }

Once I wrap it in the foreach (and change the variable to $i), your function executes without exceptions on my system.

Just realised this was in the pester forum. It would have been more suited to the Q&A forum

Moving to the appropriate forum.

I suspect that your problem is that you’re getting more than one disk returned. For instance my machine shows

PS> Get-WmiObject -Class Win32_LogicalDisk


DeviceID     : C:
DriveType    : 3
ProviderName :
FreeSpace    : 110049366016
Size         : 511210610688
VolumeName   :

DeviceID     : D:
DriveType    : 5
ProviderName :
FreeSpace    :
Size         :
VolumeName   :

Your code wants to look like this

Get-WmiObject -Class win32_LogicalDisk -Filter "DriveType=3" |
foreach {
$props = @{ 'VolumeName'=$_.VolumeName;
'Name'=$_.Name;
'Size(GB)'="{0:n2}" -f ($_.size/1GB);
'AvailableSpace(GB)'="{0:n2}" -f ($_.freespace/1gb);
'PercentFree(%)'="{0:n2}" -f ($_.freespace/$_.size*100);}
New-Object -TypeName PSObject -Property $props
}

As a further point you should be using Get-CimInstance rather than Get-WmiObject. The WMI cmdlets are deprecated.

Thank you so much liam and Richard, its working now