HI All,
I search through the internet for quite some time but couldn't find any helpful info for my script.
I'm trying to get the count of view desktops already used in a pool and the count of max. desktops.
My script shall analyse these two and send a mail to me when the normal count is reaching the max count.
As we are still in building the view enviroment, new users are added to the AD constantly so pools are filling fast.
Also we don't want huge pools therefore a fixed limit is needed and must be checked.
I thought with a script it would be the best method, can anyone help in here?
thanks
cr
Try something like this.
It will show per pool how many desktops are used.
Get-Pool | Select Pool_id,DisplayName,
@{N="#Desktops";E={$_ | Get-DesktopVM | Measure-Object | Select -ExpandProperty Count}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Maybe this will kick start you off
(Get-ResourcePool -Name "Name.Of.Pool" | Get-VM).count
Try something like this.
It will show per pool how many desktops are used.
Get-Pool | Select Pool_id,DisplayName,
@{N="#Desktops";E={$_ | Get-DesktopVM | Measure-Object | Select -ExpandProperty Count}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi All,
thanks for all your help, I got a bit further
Now I'm having the problem that I can't get any useful data out of my array^^
I use this command to fill the associative array ergs, but later I can't get any data out of it:
$ergs=(Get-Pool | Select Pool_id,@{N="desktops";E={$_ | Get-DesktopVM | Measure-Object | Select -ExpandProperty Count}},maximumcount | Format-Table -AutoSize -HideTableHeaders)
Similar if I use $ergs["VALUE"] or echo $ergs["VALUE"] or $ergs[VALUE] or $ergs['VALUE'] result is empty.
If I just use echo $ergs i can see the set Values.
Any suggestions on this?
thx
cr
You see no values because that array is not a hash table.
When you do
$ergs
you will see all the rows in the array.
To address for example the Pool_id value for the first row, you would do
$ergs[0].Pool_id
The 0 (zero) indicates you want get the 1st row of the array, and in that row you want the Pool_id property.
It's just a matter of knowing the type of the variable and how to address specific properties in the variable.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
This is also not working here, still no output.
Atm my multidimensional associative array consist of these value examples: $ergs
abb-pool1-1-v 3 3
abb-pool2-1-v 100 120
abb-pool3-2-v 50 70
Maybe the "-" is the problem?
What do the following return ?
$ergs | Get-Member
and
$ergs[0]
The '-' is in a property value, that shouldn't cause any problems
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Outout of both as following:
TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatStartData
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
autosizeInfo Property Microsoft.PowerShell.Commands.Internal.Format.AutosizeInfo autosi...
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property System.String ClassId2e4f51ef21dd47e99d3c952918aff9cd {get;}
groupingEntry Property Microsoft.PowerShell.Commands.Internal.Format.GroupingEntry group...
pageFooterEntry Property Microsoft.PowerShell.Commands.Internal.Format.PageFooterEntry pag...
pageHeaderEntry Property Microsoft.PowerShell.Commands.Internal.Format.PageHeaderEntry pag...
shapeInfo Property Microsoft.PowerShell.Commands.Internal.Format.ShapeInfo shapeInfo...
TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupStartData
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property System.String ClassId2e4f51ef21dd47e99d3c952918aff9cd {get;}
groupingEntry Property Microsoft.PowerShell.Commands.Internal.Format.GroupingEntry group...
shapeInfo Property Microsoft.PowerShell.Commands.Internal.Format.ShapeInfo shapeInfo...
TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property System.String ClassId2e4f51ef21dd47e99d3c952918aff9cd {get;}
formatEntryInfo Property Microsoft.PowerShell.Commands.Internal.Format.FormatEntryInfo for...
outOfBand Property System.Boolean outOfBand {get;set;}
writeErrorStream Property System.Boolean writeErrorStream {get;set;}
TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupEndData
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property System.String ClassId2e4f51ef21dd47e99d3c952918aff9cd {get;}
groupingEntry Property Microsoft.PowerShell.Commands.Internal.Format.GroupingEntry group...
TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatEndData
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property System.String ClassId2e4f51ef21dd47e99d3c952918aff9cd {get;}
groupingEntry Property Microsoft.PowerShell.Commands.Internal.Format.GroupingEntry group...
PS C:\Users\admin\Desktop> $ergs[0]
PS C:\Users\admin\Desktop>
I obviously didn't notice you had a Format-Table in there.
Just do
$ergs = Get-Pool | Select Pool_id,@{N="desktops";E={$_ | Get-DesktopVM | Measure-Object | Select -ExpandProperty Count}}
The Format-Table cmdlet is intended for displaying output.
As you can see from the returned types, these are special objects that are understood by the PowerShell output routine.
If you need to use objects and properties further along inside your script, do not format them (yet) for output.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I needed the Format-Table to get rid of the TableHeaders.
Iin past tests these values(pool_id, desktops, maximumcount, --------,..) were also written in the array variable which isn't really nice to handle then.
I'm just started the new creation of the array without formating, will report back soon with results.
thx
OK, now it is working, not very nice to code($erg=$ergs[4].maximumCount-$ergs[4].desktops) but as long as the result ist fine, everything is ok :smileygrin:
Only a small question to the end:
How can I get another (shorter)header for the maximumcount property e.g. "maxcou"?
Thx
You would only need that kind of addressing if you want to see the value for a specific row.
PowerShell is normally about handling a number of objects in series.
Perhaps you could share the script you are using.
There is probably a shorter way of doing this.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Actually I'm building scripts sequentially and as this function($ergs=(Get-Pool | Select Pool_id,@{N="vdesk";E={$_ | Get-DesktopVM | Measure-Object | Select -ExpandProperty Count}},maximumcount)) is the first real custom code, I haven't much to show yet.
Currently I have only:
<Adding View cmdlets>
$chk=0
$outfile="D:\outtmp.txt"
Connect-VIServer -Server server.domain.net -Force >>null
$ergs=(Get-Pool | Select Pool_id,@{N="vdesk";E={$_ | Get-DesktopVM | Measure-Object | Select -ExpandProperty Count}},maximumcount)
(below is just coded here to see the direction I want to go..(no idea if it works atm))
$lim=$ergs.count
for ($i=0;$i -lt $lim;$i++)
{
[int]$cur=$ergs[$i].maximumCount*0.05
$erg=$ergs[$i].maximumCount-$ergs[$i].vdesk
if ($erg -lt $cur)
{
echo "Pool $ergs[$i].Pool_id is reaching its limit, currently $ergs[$i].vdesk of $ergs[$i].maximumCount in use!" >> $outfile
$chk=1
}
}
(end of firstcode here)
function sendmail($body)
{
$SmtpClient = new-object system.net.mail.smtpClient
$MailMessage = New-Object system.net.mail.mailmessage
$SmtpClient.Host = "server_ip"
$SmtpClient.Port = 25
$mailmessage.from = "test@test.com"
$mailmessage.To.add("test2@test.com")
$mailmessage.Subject = “Pool monitoring”
$MailMessage.IsBodyHtml = $true
$mailmessage.Body = "$body"
$smtpclient.Send($mailmessage)
}
$body=(Get-Content $outfile) -join '<BR>'
if ($chk -eq 1)
{
sendmail $body
}
del null
del $outfile
exit
PS: how the hell can I use the code highlighting here?
cr
If I understand your script correctly, you want to send an email for each pool that has more than 95% of the desktops in use ?
If yes, then the following should do this (in a very basic way).
Get-Pool |
Where {((Get-DesktopVM -Pool_id $_.pool_id).Count/$_.maximumCount) -ge 0.95} | %{
Send-MailMessage -To "lucd@lucd.info" -From "lucd@lucd.info" `
-SmtpServer mail.lucd.info `
-Subject "$($_.pool_id) above threshold"
}
The concept is as follows:
My example only places the pool_id in the Subject of the email, but you can place whatever property in the Subject or in the Body of the email.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes you are right.
Before I test this nice function:
If I understand it corrct it send for every pool a seperate message?
Atm I plan to let the script run once a day because users aren't added in masses to the pools.
Therefore I have some time to react before a pool reachs the limit and I don't want masses of mails in my inbox because of this
No, it will only send an email for the pools that get through the Where-clause.
In other words, those pools for which 95% of the maximum is in use.
That is one of the nice features of PowerShell, you get all the objects, filter them with a condition and then take action on the objects that made it through the filter :smileycool:
You can schedule scripts with the Windows Task Scheduler.
See Alan's post called Running a PowerCLI Scheduled task
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yeah, I understood it right but explained it false in my words^^
Atm I struggling which method I should use, either sending 1 mail with infos or seperate ones.
In our enviroment we have several pools for testing which are permanently full or some has set 0 as maximum which leads the "/" to "Attempted to divide by zero." errors.
Not sure if it is good to implement filter functions here, could be more work than worth it.
Yes true, unfortunately I'm coming very slowly through the endless possibilities of PS :smileygrin:
Yep, creating a task should be no problem
I just updated a document on how to enter pretty code.
See Some ways to enter PowerCLI code under the new forum SW
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference