Solved

Powershell error with Strings

Posted on 2014-02-21
6
1,018 Views
Last Modified: 2014-02-22
I am using a script I found to generate a mailbox size report from Exchange and then email it.  It works well, but when it lists the size, I'm getting something like: "3.213 GB (26952597 Bytes).  I want to trim everything after the GB off.  That field is the object "TotalItemSize".  I'm a Powershell rookie, so here is what I *think* I have to do...

Convert the object to a string using ToString().  I then found the location of "B" in the string using IndexOf().  Then I passed that result to Remove().  When I run this step by step in PS, it works.  When I run it in a .PS1 script, I get the following error:

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         2/21/2014   1:45 PM          0 exchange2010Report.html
You cannot call a method on a null-valued expression.
At C:\Scripts\MailboxSizeReporter.ps1:100 char:36
+ $trimlength1 = $trimlength.toString <<<< ()
    + CategoryInfo          : InvalidOperation: (toString:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.
At C:\Scripts\MailboxSizeReporter.ps1:102 char:105
+ Add-Content $fileName ("<td width='15%'>" + $exdata[$alternateTableRowBackground].TotalItemSize.ToString <<<< ().Remo
ve($trimlength2) + "</td>")
    + CategoryInfo          : InvalidOperation: (ToString:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Open in new window


What am I doing wrong?

Here is my full script:

#$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://mailboxserver/PowerShell/ -Authentication Kerberos
#Import-PSSession $Session

#Variables to configure 
$mailboxServer = "mailboxserver"
$SMTPserver = "smtpserver"
$ReportSender = "report@domain.com" 
$ReportRecipient = "recipient@domain.com" 
$MailSubject = ("Mailbox Report for " + $mailboxServer + " - " + ( get-date ).ToString('yyyy/MM/dd')) 
 
#SendEmailFunction 
Function sendEmail 
{ param($smtphost,$htmlFileName) 
$smtp= New-Object System.Net.Mail.SmtpClient $smtphost 
$msg = New-Object System.Net.Mail.MailMessage $ReportSender, $ReportRecipient, $MailSubject, (Get-Content $htmlFileName) 
$msg.isBodyhtml = $true 
$smtp.send($msg) 
} 
 
$exdata = Get-MailboxStatistics -Server $mailboxServer | where {$_.ObjectClass -eq "Mailbox"} | Sort-Object TotalItemSize -descending | Select-Object DisplayName, ItemCount, TotalItemSize, Database
 
$fileName = "exchange2010Report.html" 
New-Item -ItemType file $fileName -Force 
 
# HTML start 
Add-Content $fileName "<html>" 
 
# HEAD start 
Add-Content $fileName "<head>" 
 
add-content $fileName '<STYLE TYPE="text/css">' 
add-content $fileName  "<!--" 
add-content $fileName  "td {" 
add-content $fileName  "font-family: Tahoma;" 
add-content $fileName  "font-size: 11px;" 
add-content $fileName  "border-top: 1px solid #999999;" 
add-content $fileName  "padding-top: 1px;" 
add-content $fileName  "padding-right: 0px;" 
add-content $fileName  "padding-bottom: 1px;" 
add-content $fileName  "padding-left: 2px;" 
add-content $fileName  "}" 

add-content $fileName  "th {" 
add-content $fileName  "font-family: Tahoma;" 
add-content $fileName  "font-size: 12px;" 
add-content $fileName  "border-right: 1px solid #999999;" 
add-content $fileName  "border-left: 1px solid #999999;" 
add-content $fileName  "padding-top: 1px;" 
add-content $fileName  "padding-right: 0px;" 
add-content $fileName  "padding-bottom: 1px;" 
add-content $fileName  "padding-left: 2px;" 
add-content $fileName  "}" 

add-content $fileName  "body {" 
add-content $fileName  "margin-left: 5px;" 
add-content $fileName  "margin-top: 5px;" 
add-content $fileName  "margin-right: 0px;" 
add-content $fileName  "margin-bottom: 10px;" 
add-content $fileName  "" 
add-content $fileName  "table {" 
add-content $fileName  "border: thin solid #000000;" 
add-content $fileName  "}" 
add-content $fileName  "-->" 
add-content $fileName  "</style>" 
 
# HEAD end 
Add-Content $fileName "</head>" 
 
# HEAD start 
Add-Content $fileName "<body>" 
 
# TABLE start 
Add-Content $fileName "<table width='100%'>" 
 
# TABLE Header 
Add-Content $fileName "<tr bgcolor='#7C7C7C'>" 
Add-Content $fileName "<td width='35%'>Display Name</td>" 
Add-Content $fileName "<td width='10%'>Item Count</td>" 
Add-Content $fileName "<td width='10%'>Total Item Size</td>" 
Add-Content $fileName "<td width='25%'>Database</td>" 
Add-Content $fileName "</tr>" 
 
$alternateTableRowBackground = 0 
 
# TABLE Content 
while($alternateTableRowBackground -le $exdata.length) 
{ 
if(($alternateTableRowBackground % 2) -eq 0) 
{ 
Add-Content $fileName "<tr bgcolor='#FFFFFF'>" 
} 
else 
{ 
Add-Content $fileName "<tr bgcolor='#FCFCFC'>" 
} 
Add-Content $fileName ("<td width='30%'>" + $exdata[$alternateTableRowBackground].DisplayName + "</td>")  
Add-Content $fileName ("<td width='10%'>" + $exdata[$alternateTableRowBackground].ItemCount + "</td>") 

$trimlength = $exdata[$alternateTableRowBackground].TotalItemSize.toString().IndexOf("B")+1

Add-Content $fileName ("<td width='15%'>" + $exdata[$alternateTableRowBackground].TotalItemSize.ToString().Remove($trimlength2) + "</td>")
Add-Content $fileName ("<td width='25%'>" + $exdata[$alternateTableRowBackground].Database + "</td>") 
Add-Content $fileName "</tr>" 
 
$alternateTableRowBackground = $alternateTableRowBackground + 1 
} 
# Summe Mailboxsize 
Add-Content $fileName "<tr bgcolor='#7C7C7C'>" 
Add-Content $fileName ("<td width='30%'></td>")  
$tempdata = MailboxStatistics -Server $mailboxServer | %{$_.ItemCount} | Measure-Object -Sum 
Add-Content $fileName ("<td width='10%'>" + ($tempdata | Select-Object -expand Sum) + "</td>") 
$tempdata = MailboxStatistics -Server $mailboxServer | %{$_.TotalItemSize.Value.ToMB()} | Measure-Object -Sum 
Add-Content $fileName ("<td width='15%'>" + ($tempdata | Select-Object -expand Sum) + " MB</td>") 
Add-Content $fileName ("<td width='25%'></td>")  
 
#TABLE end 
Add-Content $fileName "</table>" 
 
# HEAD end 
Add-Content $fileName "</body>" 
 
# HTML end 
Add-Content $fileName "</html>" 
 
sendEmail $smtpServer $fileName

Open in new window

0
Comment
Question by:ddotson
  • 3
  • 2
6 Comments
 
LVL 40

Expert Comment

by:footech
ID: 39878399
Can you provide the unmodified script?  It'll be easier to modify that than to work backward.
0
 

Author Comment

by:ddotson
ID: 39878492
Here is the original code from http://gallery.technet.microsoft.com/office/Exchange-2010-Mailbox-Size-c3746baf

#Variables to configure 
$MailServer = "srv-mail-01" 
$ReportSender = "sender@yourdomain.local" 
$ReportRecipient = "recipient@yourdomain.local" 
$MailSubject = ("yourdomain.local exchange2010 Mailbox Report for " + $MailServer + " - " + ( get-date ).ToString('yyyy/MM/dd')) 
 
#SendEmailFunction 
Function sendEmail 
{ param($smtphost,$htmlFileName) 
$smtp= New-Object System.Net.Mail.SmtpClient $smtphost 
$msg = New-Object System.Net.Mail.MailMessage $ReportSender, $ReportRecipient, $MailSubject, (Get-Content $htmlFileName) 
$msg.isBodyhtml = $true 
$smtp.send($msg) 
} 
 
$exdata = Get-MailboxStatistics -Server $MailServer | Sort-Object TotalItemSize -descending | Select-Object DisplayName, ItemCount, TotalItemSize, Database, StorageLimitStatus 
 
$fileName = "exchange2010Report.html" 
New-Item -ItemType file $fileName -Force 
 
# HTML start 
Add-Content $fileName "<html>" 
 
# HEAD start 
Add-Content $fileName "<head>" 
 
add-content $fileName '<STYLE TYPE="text/css">' 
add-content $fileName  "<!--" 
add-content $fileName  "td {" 
add-content $fileName  "font-family: Tahoma;" 
add-content $fileName  "font-size: 11px;" 
add-content $fileName  "border-top: 1px solid #999999;" 
add-content $fileName  "border-right: 1px solid #999999;" 
add-content $fileName  "border-bottom: 1px solid #999999;" 
add-content $fileName  "border-left: 1px solid #999999;" 
add-content $fileName  "padding-top: 0px;" 
add-content $fileName  "padding-right: 0px;" 
add-content $fileName  "padding-bottom: 0px;" 
add-content $fileName  "padding-left: 0px;" 
add-content $fileName  "}" 
add-content $fileName  "body {" 
add-content $fileName  "margin-left: 5px;" 
add-content $fileName  "margin-top: 5px;" 
add-content $fileName  "margin-right: 0px;" 
add-content $fileName  "margin-bottom: 10px;" 
add-content $fileName  "" 
add-content $fileName  "table {" 
add-content $fileName  "border: thin solid #000000;" 
add-content $fileName  "}" 
add-content $fileName  "-->" 
add-content $fileName  "</style>" 
 
# HEAD end 
Add-Content $fileName "</head>" 
 
# HEAD start 
Add-Content $fileName "<body>" 
 
# TABLE start 
Add-Content $fileName "<table width='100%'>" 
 
# TABLE Header 
Add-Content $fileName "<tr bgcolor='#7C7C7C'>" 
Add-Content $fileName "<td width='35%'>DisplayName</td>" 
Add-Content $fileName "<td width='10%'>ItemCount</td>" 
Add-Content $fileName "<td width='10%'>TotalItemSize</td>" 
Add-Content $fileName "<td width='25%'>Database</td>" 
Add-Content $fileName "<td width='20%'>StorageLimitStatus</td>" 
Add-Content $fileName "</tr>" 
 
$alternateTableRowBackground = 0 
 
# TABLE Content 
while($alternateTableRowBackground -le $exdata.length) 
{ 
if(($alternateTableRowBackground % 2) -eq 0) 
{ 
Add-Content $fileName "<tr bgcolor='#CCCCCC'>" 
} 
else 
{ 
Add-Content $fileName "<tr bgcolor='#FCFCFC'>" 
} 
Add-Content $fileName ("<td width='30%'>" + $exdata[$alternateTableRowBackground].DisplayName + "</td>")  
Add-Content $fileName ("<td width='10%'>" + $exdata[$alternateTableRowBackground].ItemCount + "</td>") 
Add-Content $fileName ("<td width='15%'>" + $exdata[$alternateTableRowBackground].TotalItemSize + "</td>") 
Add-Content $fileName ("<td width='25%'>" + $exdata[$alternateTableRowBackground].Database + "</td>") 
#BelowLimit or NoChecking 
if(($exdata[$alternateTableRowBackground].StorageLimitStatus -eq "BelowLimit") -or ($exdata[$alternateTableRowBackground].StorageLimitStatus -eq "NoChecking")) 
{ 
Add-Content $fileName ("<td bgcolor='#007F00' width='20%'>" + $exdata[$alternateTableRowBackground].StorageLimitStatus + "</td>") 
} 
#IssueWarning 
if($exdata[$alternateTableRowBackground].StorageLimitStatus -eq "IssueWarning") 
{ 
Add-Content $fileName ("<td bgcolor='#7F7F00' width='20%'>" + $exdata[$alternateTableRowBackground].StorageLimitStatus + "</td>") 
} 
#ProhibitSend or MailboxDisabled 
if(($exdata[$alternateTableRowBackground].StorageLimitStatus -eq "ProhibitSend") -or ($exdata[$alternateTableRowBackground].StorageLimitStatus -eq "MailboxDisabled")) 
{ 
Add-Content $fileName ("<td bgcolor='#7F0000' width='20%'>" + $exdata[$alternateTableRowBackground].StorageLimitStatus + "</td>") 
} 
Add-Content $fileName "</tr>" 
 
$alternateTableRowBackground = $alternateTableRowBackground + 1 
} 
# Summe Mailboxsize 
Add-Content $fileName "<tr bgcolor='#7C7C7C'>" 
Add-Content $fileName ("<td width='30%'></td>")  
$tempdata = MailboxStatistics -Server $MailServer | %{$_.ItemCount} | Measure-Object -Sum 
Add-Content $fileName ("<td width='10%'>" + ($tempdata | Select-Object -expand Sum) + "</td>") 
$tempdata = MailboxStatistics -Server $MailServer | %{$_.TotalItemSize.Value.ToMB()} | Measure-Object -Sum 
Add-Content $fileName ("<td width='15%'>" + ($tempdata | Select-Object -expand Sum) + " MB</td>") 
Add-Content $fileName ("<td width='25%'></td>") 
Add-Content $fileName ("<td width='20%'></td>") 
 
 
#TABLE end 
Add-Content $fileName "</table>" 
 
# HEAD end 
Add-Content $fileName "</body>" 
 
# HTML end 
Add-Content $fileName "</html>" 
 
sendEmail $MailServer $fileName

Open in new window

0
 
LVL 34

Accepted Solution

by:
Dan Craciun earned 300 total points
ID: 39878807
Have you tried something like:
$TIS = @{N = "TotalItemSize"; E = {$exdata[$alternateTableRowBackground].TotalItemSize.Value.ToMB()}}
Add-Content $fileName ("<td width='15%'>" + $TIS["E"] + "</td>") 

Open in new window

Replace lines 102-104 in your script.

HTH,
Dan
0
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 

Author Comment

by:ddotson
ID: 39878850
I haven't.  If I read your code correctly, it will convert the value contained in the variable to megabytes.  Currently, it will display in the unit that is most appropriate - could be GB, MB, or KB.  I don't know how or why it's doing it, but it's very useful.  If I insert this code, then it stays in MB no matter what, correct?

I like the fact that it displays in the units most appropriate for the size...
0
 
LVL 40

Assisted Solution

by:footech
footech earned 200 total points
ID: 39878884
Dan's method may very well work for you.  I have an Office 365 environment so I have to modify the script to get it to work, and I think the form of the data is a bit different so the ToMB() method isn't available.

What I found works for me is if I modify line 16 from the original code (equates to line 20 in yours) to the following.  Then no more modifications should be needed.
$exdata = Get-MailboxStatistics -Server $MailServer | Sort-Object TotalItemSize -descending | Select-Object DisplayName, ItemCount, @{n="TotalItemSize";e={($_.totalitemsize -split " \(")[0]}}, Database

Open in new window


If you're working with a local server then the command might have to be more like
$exdata = Get-MailboxStatistics -Server $MailServer | Sort-Object TotalItemSize -descending | Select-Object DisplayName, ItemCount, @{n="TotalItemSize";e={($_.totalitemsize.ToString() -split " \(")[0]}}, Database

Open in new window


If neither of those works for you, could you provide me with the output from running
Get-MailboxStatistics -Server $MailServer | Sort-Object TotalItemSize -descending | Select-Object TotalItemSize | gm

Open in new window

and maybe
Get-MailboxStatistics -Server $MailServer | Sort-Object TotalItemSize -descending | Select-Object -expand TotalItemSize | gm

Open in new window

0
 

Author Closing Comment

by:ddotson
ID: 39879892
This worked very well.  Thank you so much!  I knew formatting on the front end would be the best way, rather than trying to format the result.
0

Featured Post

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Learn to move / copy / export exchange contacts to iPhone without using any software. Also see the issues in configuration of exchange with iPhone to migrate contacts.
This article explains how to install and use the NTBackup utility that comes with Windows Server.
The video tutorial explains the basics of the Exchange server Database Availability groups. The components of this video include: 1. Automatic Failover 2. Failover Clustering 3. Active Manager
This video demonstrates how to sync Microsoft Exchange Public Folders with smartphones using CodeTwo Exchange Sync and Exchange ActiveSync. To learn more about CodeTwo Exchange Sync and download the free trial, go to: http://www.codetwo.com/excha…

837 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question