Attempted to divide by 0

This topic contains 9 replies, has 4 voices, and was last updated by  Sethuraman 3 weeks ago.

  • Author
    Posts
  • #83069

    Sethuraman
    Participant

    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
    }

  • #83072

    Liam Kemp
    Participant

    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

    • #83075

      Sethuraman
      Participant

      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.

  • #83077

    Liam Kemp
    Participant

    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

    • #83080

      Sethuraman
      Participant

      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
      }
      }

  • #83083

    Liam Kemp
    Participant

    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.

    • #83267

      Sethuraman
      Participant

      Thank you so much liam and Richard, its working now

  • #83104

    Liam Kemp
    Participant

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

  • #83129

    Adam Bertram
    Moderator

    Moving to the appropriate forum.

  • #83167

    Richard Siddaway
    Moderator

    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.

You must be logged in to reply to this topic.