Solved

Powershell error with Strings

Posted on 2014-02-21
6
964 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 39

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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

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 39

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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Disabling the Directory Sync Service Account in Office 365 will stop directory synchronization from working.
Scam emails are a huge burden for many businesses. Spotting one is not always easy. Follow our tips to identify if an email you receive is a scam.
In this video we show how to create a Distribution Group in Exchange 2013. We show this process by using the Exchange Admin Center. Log into Exchange Admin Center.: First we need to log into the Exchange Admin Center. Navigate to the Recipients >>…
To show how to create a transport rule in Exchange 2013. We show this process by using the Exchange Admin Center. Log into Exchange Admin Center.: First we need to log into the Exchange Admin Center. Navigate to the Mail Flow >> Rules tab.:  To cr…

759 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now