Jump to content
Software FX Community

JuanC

Staff
  • Posts

    863
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by JuanC

  1. Unfortunately we are not aware of any way of hooking into how PowerShell runs "native" commands to avoid displaying the console window. The following is a mix of Lee Holmes post and Tim Scarfe post to try to generate a script that you can call when invoking native commands: Contents of gpo.ps1 (get-processoutput) param([string] $processname, [string] $arguments) $psi = New-Object System.Diagnostics.ProcessStartInfo $psi.CreateNoWindow=1 $psi.RedirectStandardOutput = 1 $psi.UseShellExecute=0 $psi.FileName = $processname if ($arguments) { $psi.Arguments = $arguments } $process = [system.Diagnostics.Process]::Start($psi) $process.WaitForExit() $output = $process.StandardOutput.ReadToEnd() $str = new-object System.String 13,1 foreach($line in $output.Split(10)) { $line.Replace($str,"") } The lines after ReadToEnd are my contribution and I am not terribly proud of them, but it was the closest I got to try to mimic the output you get when you run the commands natively. There is one difference though between running ping natively and using gpo that you can see from the following PS C:\>$a = ping www.google.com -n 1 PS C:\>$a[0] PS C:\>$a[1] PS C:\>$a[2] Pinging www.google.com [64.233.161.99] with 32 bytes of data: PS C:\>$a = gpo ping "www.google.com -n 1" PS C:\>$a[0] PS C:\>$a[1] Pinging www.google.com [64.233.161.99] with 32 bytes of data: So even though when you run both commands the output looks identical, it seems as I am still not breaking the lines in the same way they do. If you ask me, I would say the empty line you get when running ping should be line0 and the "Pinging ..." line should be line1 so using gpo could make the line guessing game a little easier :-) Now if you modify ping1.ps1 as follows $output = gpo ping "www.google.com -n 1" $output[3].split(" =")[ 6 ].replace("ms","") You will get out-gauge to refresh properly without the flashing console window. Regards, JuanC
  2. There are several properties for the labels to play with, obviously these can be combined. This is an interesting topic so we will probably add a blog post in the future. - Affect how much vertical space the X axis can use, note that we may sill hide some labels if we consider the labels will overlap with each other. ps | out-chart -label ProcessName -values cpu -axisx_MaxSizePercentage 50 - Force all labels to be shown, note that we have an algorithm that selects whether we should set the labels at 45 or 90 degrees, by setting the Step property you assume responsibility of selecting the angle ps | out-chart -label ProcessName -values cpu -AxisX_Step 1 -AxisX_LabelAngle 90 - Change the font ps | out-chart -label ProcessName -values cpu -AxisX_Font "Tahoma, 6" Note that if you incorporate our tab-completion improvements, you will be able to quickly browse through many interesting properties by typing out-chart -axisX_<TAB> Regards, JuanC
  3. We are currently working on our service pack/hotfix infrastucture. The current plan is to provide a Web Service that will return the current build number. This will allow you to use invoke-webservice to retrieve it. We will post the URLs here as soon as they are operational. JuanC
  4. The getColor function along with the 3 assignments will only work if your script actually returns 3 (or more elements). In the particular test you ran, you are also hitting an issue where if your script only returns 1 item then you cannot use [ ] as your script is not returning an array of items but only that particular item. To fix this issue in your code you have 2 choices a) Prepare your chart script to handle any number of items returned by the data script, to do this change those 3 assignments so that your code can handle less items including only one or zero, note again that you may have to check first if the script actually returned a collection or just one item. Make sure your data script always returns 3 items (Error, Warning and Information). To do this I would add 3 0s to a hash indexed by a string (Error, Warning and Information), then loop through the real data replacing the appropriate items in the hash. Finally you would have to make sure you return 3 objects so that the chart (or any other cmdlet) can process them. We will keep researching if there is an easier and hopefully more general way to assign colors (and maybe other properties) based on a non-numerical property. JuanC
  5. We do not have any code in PowerGadgets that would allow you to retrieve data from a hashtable. this sounds interesting for future builds but I see at least the following options - If there is 1 value per key, use the keys as labels and plot the values- If there are arrays as values, we could treat each key/array as a series or each value in the array as a different series.- Should we also handle if there are complex objects in the hash? At this point, if you need the hash because you need to "consolidate" values, you will have to loop through your hash and create objects and then pass an array/list of these objects to out-chart. JuanC
  6. Note that your output looks like this PathName :ManagementGroup : OpsMgr DemoManagementServerName : 192.168.0.3Drives : Count Name ----- ---- 6 Error So your script is actually returning first an object with 4 properties (PathName, ManagementGroup, etc.) none of which are numbers, followed by the information you want to chart, You want your script to return just the following Count Name ----- ---- 6 Error I do not have OpsMgr installed but it seems to me the call to new-managementGroupConnection is actually returning an object. One way to work around this would be to do $obj = new-managementGroupConnection When you were running a combined script this was still happening but it did not affect you because you were only piping the get-alert to the chart, now that you are piping the script as a whole you have to be careful that your script does not return something you don't want. JuanC
  7. Can you post the output you get when you run the following d:\scripts\PromptOpsMgrAlerts.ps1 -serverName ServerNameGoesHere -account AccountGoesHere Is it possible your script simply returned no alerts? JuanC
  8. Your script is tricky in more than one sense so I added a blog post trying to explain some of the reasons why we may fail to refresh a script. http://community.softwarefx.com/blogs/powergadgets_team_blog/archive/2007/02/22/Writing-refreshable-scripts-for-PowerGadgets.aspx BTW, Marco was right on track on the post he deleted :-) JuanC
  9. Although most scripts should refresh fine in PowerGadgets, there are some things you need to be aware of when writing those scripts. In order to debug your script refreshability (not sure this is a word but it sounds ok), I would recommend not using -refresh but instead right click the chart/gauge/map and select Refresh. Once your script is working you will obviously use -refresh with the desired refresh rate. Also if you have a Vista machine handy you may want to test there. In the current bits we show a MessageBox in XP but in Vista you can click "See Details" to get a little more information about any exceptions we encounter. Security Issues To illustrate the security issues you may experience I will write a script that gets some information about IIS servers using WMI. This is very similar to this post although to focus on drilldown I made myself an admin on my previous post to avoid any credentials issues. This time I am not an admin so to connect to IIS6 using WMI we need to authenticate ourselves. Let's start with a hardcoded script (HardcodedIIS.ps1) $serverName = "webserver1" Get-WmiObject Win32_PerfFormattedData_W3SVC_WebService -computername $serverName -filter "Name='_Total'" -property __SERVER, CurrentConnections -credential yourDomain\Administrator | select CurrentConnections If you execute HardCodedIIS you will get a powershell prompt requesting the password for the Administrator account, if the password is accepted you will get the current connections for all the sites in your web server. At this point if you execute HardCodedIIS | out-chart you will get a bar chart but if you click Refresh you will get prompted again. Although this doesn't sound too good, note that any subsequent refreshes will not prompt again as we cache the credential and reuse it for the life of this particular gadget. To try to fix this we implemented a parameter in newer builds (tentatively called -CacheCredential), when you use this parameter we try to reuse the credentials but it only works under the following circumstances a) You use a variable of type credential The "command line" that precedes out-chart uses this credential as a parameter on a cmdlet and not a script Imagine you type the following in an interactive powershell session $cred = get-credential softwarefx\Administrator Get-WmiObject Win32_PerfFormattedData_W3SVC_WebService -computername WebServer1 -filter "Name='_Total'" -property __SERVER, CurrentConnections -credential $cred | select CurrentConnections | out-chart -CacheCredential The reason for (a) is that in order to implement refresh we have to reexecute the command that precedes us (note that in this case is the get-wmiobject) and we can see that you are using a variable of type credential, this is unfortunate as -credential domain\Admin does not work but I would not consider this a showstopper. Reason ( on the other hand is definitely a showstopper, if you try to put the "get-wmiobject ... | select CurrentConnections" line in a script that receives one param you will see that again we reprompt the credentials once more. It seems to me that PowerShell does not treat equally a cmdlet that exposes a PSCredential parameter from a script that declares a param of type PSCredential. I can only guess that this is because we cannot adorn the script parameter with the [Credential()] attribute as in the cmdlet but only somebody from the PowerShell team would know if this is in fact the case. Bottom line, when using authentication you will get authenticated once more the first time a gadget is refreshed. We will try to fix this in future builds. Read Host One of the obvious improvements you would do to HardCodedIIS would be to prompt both for the server name and account as follows, this new script (PromptIIS.ps1) is much better as you can now use it for any web servers in your domain. param ([string]$serverName = $(read-host "Please enter the web server name"), [string]$account = $(read-host "Please enter your domain\username account")) Get-WmiObject Win32_PerfFormattedData_W3SVC_WebService -computername $serverName -filter "Name='_Total'" -property __SERVER , CurrentConnections -credential (get-credential $account) | select __Server , CurrentConnections If you try now to do PromptIIS | out-chart and hit refresh you will get an error "Failed to Connect to Data" and the details will say "Cannot invoke this function because the current host does not implement it". In the future we may implement read-host and show a dialog prompting for the required parameters but hopefully what you want is for the current server name and account to be reused. In order to achieve this you will have to create a separate PromptIISChart.ps1 as follows param ([string]$serverName = $(read-host "Please enter the web server name"), [string]$account = $(read-host "Please enter your domain\username account")) PromptIIS -serverName $serverName -account $account | out-chart When running PromptIISChart you will get the prompt for the parameters but the refresh command will include the parameters you used, because of this PromptIIS will not need to reprompt and refresh will work as expected (although you will have to provide your password once more). Separate the data from the presentation in your scripts There are 2 main reasons why we think this is a good idea, first it allows you to reuse your scripts in several situations, e.g. if you have a script that returns a collection of objects, you can pipe them to out-chart to see trends or you can use measure-object to count the items and pass it to out-gauge. Additionally you can invoke your script and pipe it to where/sort/etc before passing it to the chart The second reason is a technical one, when refreshing we only reexecute the command that precedes our cmdlets in the same line, this can be illustrated in the following pseudo script $data1 = get-cmdlet1 ... $data2 = get-cmdlet2 -param $data1 get-cmdlet3 -param $data2 | out-chart If you try to refresh this chart, we are only aware of "get-cmdlet3 -param $data2" and this will only work if $data2 is a string or number but not if it is an object. Note that we will NOT try to execute the get-cmdlet1 and -get-cmdlet2 calls are we are not even aware of them. Because of this you will have to break this up in two scripts. This means that your data script will have all the get-cmdlet* calls so all of them will be reexecuted when you type DataScript | out-chart Acknowledgment This post was inspired by the OpsMgr script written by Stefan Stranger and in particular this thread. JuanC
  10. Yes, provided that there is no other possible name, the resulting order will be Error, Information and then Warning. Note that the script I included in my post would allow you to assign specific colors to these labels and still allow you to order them in any other way, e.g. by Count. JuanC
  11. You can use the -topmost parameter to create a gadget that remains on top of all other windows. e.g. out-gauge -floating -topmost JuanC ResizeDrawingObject.zip
  12. Tab Completion and how it can be modified is an interesting feature in PowerShell, for our particular cmdlets we actually improved on it in several ways. Enumerations Enumeration values are listed when appropriate, e.g. out-chart -gallery <TAB> will list Lines, Area, Bar, Pie and all the gallery types supported by the -gallery parameter. Formatted values Certain parameters require specially formatted values, examples of this are Font, Size, Color and TimeSpan. By typing out-chart -font <TAB> you will get a preview of the format required to specify a font. Runtime values In certain properties we can actually use runtime information for tab completion: out-chart -sidebar <TAB> will list all the PowerGadgets gadgets currently running in the Vista sidebar. Works for all 3 cmdlets. out-gauge -template <TAB> will list all the PGT files in the documents folder. Works for all 3 cmdlets. out-map -mapsource <TAB> will list all the map files (SVG) in the map library folder. Note that we will also list subdirectories, to get the files in one of the listed folders append a backslash and type <TAB> again. Subobjects In order to implement all the functionality in our controls we obviously grouped the exposed API in different classes, you access these classes with the underscore (-) character after the object name, e.g. in out-chart we expose an AxisX and AxisY objects, both implement similar functionality as both are an Axis. You get to any axis property by typing out-chart -axisy_<TAB> you will get a list of the properties supported by an Axis object. Note that sometimes objects will in turn contain other objects, for example typing out-chart -axisy_labelsformat_<TAB> will list the properties that allow you to control the formatting of the labels in an axis (Decimals, Format, Culture, etc.) You may be asking yourself at this point why your PowerShell session does not expose any of this tab-completion features, the reason is that tab completion is controlled by a function in your profile, you can read more about profiles here, but most of the time you will create a file named profile.ps1 and place it in a subdirectory of your Documents folder called WindowsPowershell. Because trying to mix your current profile was not a practical approach, we decided to just ship a file named profile.ps1, it contains a modified version of the built-in tabexpansion function. If you do not have a profile all you have to do is copy this file to the appropriate folder. If you already have one you will have to merge the contents of both files, possibly merging the contents of the tabcompletion functions, if you already had one. The modifications we did to this function are highlighted in this picture (some details of the function were replaced with ...) If anybody from the PowerShell team is reading this, I think this would be a nice improvement for future versions. Some way to allow cmdlets to enhance tab completion for their use without actually having to modify the profile function (e.g. a static function with a predefined name in the cmdlet class). Obviously being able to hook into the tab completion with a function in your profile allows you to customize this process in very interesting ways but if multiple cmdlets want to enhance tab completion you can see how the model starts to complicate. JuanC
  13. First, an explanation of the results you are getting, PowerGadgets charts will use one color per series in the chart, by default each series corresponds with a numerical column in your data so in your case there is 1 series (Count) and 3 points. There are 2 ways to get multiple colors in your chart in your scenario alerts | out-chart -datasourcesettings_style +Transpose In this case you are telling us to transpose your data, this means your chart will now have 3 series (Error, Warning, Info) and 1 Point (labeled count). Note that this would also work if you were data was returning more than 1 numerical column, e.g. Count and YesterdayCount alerts | out-chart -allseries_multiplecolors true In this case the chart still has 1 series and 3 points but you are telling us to use colors on a per-point basis instead of per-series. This approach works better when you have only one numerical column in your data. Note that in both cases the colors we choose depend on the palette, if you want to customize the colors you would do something like alerts | out-chart -datasourcesettings_style +Transpose -series_0_color Red -series_1_color Yellow -series_2_color Green or alerts | out-chart -allseries_multiplecolors true -points_0_color Red -points_1_color Yellow -points_2_color Green One important issue in both commands, you are implicitly depending on the order of your data when assigning colors. If you can live with any ordering (e.g. Errors then Information then Warnings) then you can make your life easier by changing sort-object to sort by Name and change your colors accordingly. I am afraid we do not have a simple way of assigning colors depending on labels so one way you could achieve this would be doing this on an alternate script (alertsChart.ps1) function getColor{ if ($args[0] -eq 'Error') { return 'Red' } if ($args[0] -eq 'Warning') { return 'Yellow' } if ($args[0] -eq 'Information') { return 'Green' } return 'Black'} $items = alerts$clr0 = getColor $items[0].Name$clr1 = getColor $items[1].Name$clr2 = getColor $items[2].Name $items | out-chart -allseries_multiplecolors true -points_0_color $clr0 -points_1_color $clr1 -points_2_color $clr2 Probably not the one-liner you had in mind but it gets the job done. Regards, JuanC
  14. There is only one feature we are aware of that is not implemented in x64 platforms at this time: Digitally signing a PGF and checking its signature. We plan to implement this in a future build. Most of our developers are using Vista x64 so we know we are shipping all the required C++ components compiled for the x64 platform. Regards, JuanC
  15. When we say personalization we are referring to a feature in PowerGadgets where gadgets will remember previously used settings, these can be simple such as window location and size or customizations to any visual attributes e.g chart colors, gallery type, fonts, etc. This is particular handy for floating gadgets as you can place them in a specific location in your desktop and they will remember their layout for future sessions. Personalized gadgets are simply files saved with a PGT extension (as they are in fact identical to templates you create using the -config parameter). The location of these files is a subdirectory of the current user's roaming profile and the actual path depends on the operating system. In Vista:C:\Users\<YourUserName>\AppData\Roaming\PowerGadgets, LLC\PowerGadgets\Personalization In XP:C:\Documents and Settings\<YourUserName>\Application Data\PowerGadgets, LLC\PowerGadgets\Personalization Some of the implementation details depend on how gadgets are created, also note that gadgets in the sidebar are handled differently than desktop gadgets. We will talk about sidebar personalization in a future post. PowerShell Gadgets By default PowerShell created gadgets will not be personalized as we need some way to identify a specific gadget, this is done when you use the -name parameter as follows ps | out-chart -values WorkingSet -name PSCHart By assigning a name we can now store and remember any personalizations to the gadget. A file named PSChart.pgt will be saved if you modify any of the gadget settings. Groups are a little different, e.g. ps | out-chart -values WorkingSet -group MyGroup -name Processesget-date -uformat %r | out-gauge -group MyGroup -name Time In this case we will save the global settings such as window size and location in a file named MyGroup.pgt while visual attributes will be saved on MyGroup.Processes.pgt and MyGroup.Time.pgt. Note that we also use the name to label the current tab in a gadget group. PowerGadgets Creator Gadgets generated using Creator are automatically personalized, to support this we generate a GUID when a gadget file is created or you use the Save As menu option, this means that personalization templates will have very long names but we do not expect users to handle these files and it allows us to expose this feature without the need to prompt a name. This also means that personalizations are not lost if you rename your gadget files or move them to a different folder. In groups, the file names for individual items in a group are saved concatenating the GUID with the item's index. Personalizations also use a sort of version number, when you make modifications to a PGF PowerGadgets creator will increment its version so that old customizations are ignored, additionally you can turn off personalization by unchecking the "Edit - Desktop Settings - Personalizable" menu item. Note that these GUIDs used for personalization only so if you want 2 or more PGF files to share its personalizations you could use notepad or any other text editor to copy the <GUID> tag. JuanC
  16. To show how DrillDown_script allows you to interactively analyze your data and link multiple PowerShell scripts we will build a series of scripts used to monitor multiple IIS web servers. We will start with a chart showing Current Connections for all of our servers. IISServers.ps1 $servers = "webserver1", "webserver2", "webserver3" Get-WmiObject Win32_PerfFormattedData_W3SVC_WebService -computername $servers -filter "Name='_Total'" -property __SERVER, CurrentConnections | select __Server,CurrentConnections I tried to speed this script by both filtering and specifying the output properties at the get-wmiobject call, trying to minimize network traffic and hopefully wmi execution but it still feels a little sluggish. If you know how to improve the performance of this remote wmi command please add a comment to this post. IISServers | out-chart -drilldown_script IISServer -drilldown_parameter {$_.__Server} -refresh 0:0:30 -legendbox_visible false Now we need to make sure our IISServer.ps1 script handles a parameter which will have one of the server names, on this script we will list information on a per-site basis, please be aware that when you double click on a bar you will get detailed information for the specific server but on a busy server this new detailed information might be different than the "Total" showed on the previous chart as it will be fresh data. IISServer.ps1 $computer = $args[0] $title = "Current Connections for " + $computer Get-WmiObject Win32_PerfFormattedData_W3SVC_WebService -computername $computer -property __SERVER, Name, CurrentConnections | select Name, CurrentConnections, __SERVER | where {$_.Name -ne "_Total"} | out-chart -title $title -drilldown_script IISSite -drilldown_parameter {$_.__Server},{$_.Name} -refresh 0:0:30 -gallery pie Note that in this script we are actually getting the data and immediately sending it to the chart, normally we recommend you try to keep your "data/business-layer" scripts separated from the presentation scripts but this make this sample a little easier. You could split it into 2 scripts if desired. Also note we are again piping the server name to the out-chart cmdlet, we do this in order to be able to pass this parameter to our third script when double clicking. Finally IISSite.ps1 will show the real-time trend information for a specific site on a server, in this case because the script will return one "record" of information, out-chart will automatically add points every time the refresh timer ticks. IISSite.ps1 $computer = $args[0] $site = $args[1] $title = "Site " + $site + " on " + $computer $filter = "Name = '"+$site+"'" Get-WmiObject Win32_PerfFormattedData_W3SVC_WebService -computername $computer -filter $filter -property Name, CurrentConnections, BytesTotalPersec | select Name, CurrentConnections, BytesTotalPersec | out-chart -values CurrentConnections,BytesTotalPersec -refresh 0:0:30 -disableauto AxisY -series_1_axisy AxisY2 -gallery Lines -title $title -legendbox_dock bottom -axisy_TextColor DarkBlue -axisy2_TextColor DarkRed Some notes about this chart We are using -disableAuto and -series1_axisy in the out-chart cmdlet, normally PowerGadgets will analyze your data to see if multiple Y axes are required, this analysis is not repeated when adding points to avoid an axis suddenly appearing/disappearing. We want to make sure we force the use of 2 Y axes in case the data for CurrentConnections and BytesTotalPerSec on the first point collected are both small as later they will most likely differ. The legend window will be placed at the bottom using -legendbox_dock to improve space usage. We are changing the color used to paint the axis labels to make more clear the relation between each line and its axis, if you hover one of the lines or the legend box we will also highlight the appropriate element while dimming non-related items. When PowerGadgets detects a realtime chart that adds points is not using X axis labels it will automatically set the label to the time the data was collected. DrillDown to a console window Sometimes listing text is actually the best choice, if you want to drilldown to a script that just outputs data to the console you can do so by adding the -drilldown_console flag, e.g. if double clicking on a server in IISServer.ps1 should just list all web sites including the number of connections for each site you would remove the out-chart call in IISServer.ps1 so that it just returns the request data and then add -drilldown_console to the out-chart that gets data from IISServers.ps1. If you forget to add -drilldown_console we will still run IISServer.ps1 but you will not see its output. I try to make most of the sample code in my posts not to require any attachments (databases, etc.) as I feel this gives you a chance of quickly experimenting with it, obviously if you are using invoke-sql to connect gadgets to databases you can easily apply the concepts in this post to add drill down interactivity to your gadgets. JuanC
  17. This is a bug where we are internally resetting the gadget size to 0 when set to Custom. We have fixed this issue in our current build, If you want to get it before it is released as a public build, please contact tech support (see website for details). Note that after getting a new build you will have to remove the personalization of this gadget or resave it using the creator, we will add a blog post about this feature soon (I will add a reply with a link to the article as soon as it is uploaded) JuanC
  18. The licensed version you are using is probably out of date. You can check the version of the installer by right clicking on the installer exe and check the FileVersion. Note that our most recent trial is build 2588. JuanC
  19. Another option would be to use our gradient fill mode instead of using conditional attributes, in this mode bar/area charts will use gradient from the "main color" (up) to the "alternate color" (down). 10,5,20,12,14,18,6 | out-chart -gallery area -AllSeries_FillMode gradient -palette highcontrast -Series_0_AlternateColor DarkBlue10,5,20,12,14,18,6 | out-chart -gallery area -AllSeries_FillMode gradient -palette highcontrast -Series_0_Color "#FF00FF00" -Series_0_AlternateColor "#2000FF00" Note that in the second sample we are specifying both the main and alternate color and using a semi transparent color for alternate. JuanC cfxzoom.wmv
  20. There are some cmdlet parameters in PowerGadgets where we support powershell script blocks, although its support may not be obvious. We think they enable important scenarios so I will try to describe them here. Parameters that normally specify fields: In out-chart (or out-map) the -values and -label parameters allow you to specify one or more fields to be plotted and the field to be used as labels. Both parameters support scriptblocks which allow the following: ps | out-chart -values {$_.WorkingSet/$_.Handles} ps | out-chart -values @{Expression={$_.WorkingSet/$_.Handles};Name="WorkingSet per Handle"} ps | out-chart -values CPU -label {$_.ProcessName + "-" + $_.ID} Note that the expression will also be used as the series title, to fix this you can use trick in the second line where a hashtable is created with 2 elements, the expression and the name to be used, you may need to resize the chart vertically to see the labels in the third sample. Almost any out-gauge parameter Because out-gauge is normally used to display one value, we can use additional fields in the data for almost any parameter supported by out-gauge, e.g. imagine you want a digital panel that changes color when the displayed value is bigger than a specified value. RandomData.ps1 $random = new-object System.Random $value = [system.Int32] ($random.NextDouble() * 20); $prevValue = [system.Int32] ($random.NextDouble() * 20); $color = "Green" if ($value -lt 8) { $color = "Red" } $obj = new-object System.object add-member -inputobject $obj -membertype NoteProperty -Name Sales -value $value add-member -inputobject $obj -membertype NoteProperty -Name Color -value $color add-member -inputobject $obj -membertype NoteProperty -Name PrevSales -value $prevValue $obj This script returns an object with 3 properties the value to be displayed and a color property which depends on the value (PrevSales will be used in our next sample), you can then use this data as follows .\Randomdata.ps1 | out-gauge -type digital -value Sales -appearance_color {$_.Color} -refresh 0:0:2 .\Randomdata.ps1 | out-gauge -type radial -value Sales -mainindicator_color {$_.Color} -refresh 0:0:2 /TeamBlogImages/ScriptBlocksupportinPowerGadgets_D4C/image02.png /TeamBlogImages/ScriptBlocksupportinPowerGadgets_D4C/image04.png A similar scenario would be to show a value for the current year/month in a gauge while at the same time showing the value for the previous year/month as a reference. .\Randomdata.ps1 | out-gauge -type radial -value Sales -mainscale_indicators_add marker -mainscale_indicators_1_size 0.75 -mainscale_indicators_1_value {$_.PrevSales} /TeamBlogImages/ScriptBlocksupportinPowerGadgets_D4C/image0_thumb1.png In this case we are adding an indicator to the main scale and then settings its size to be 0.75, the value property for this marker will be the PrevSales property returned by our script. If you want to customize this further you would probably want to use our template editor (out-gauge -config), create a template with an extra indicator, set any of its properties and then use this template as follows .\Randomdata.ps1 | out-gauge -type radial -value Sales -template ExtraIndicator -mainscale_indicators_1_value {$_.PrevSales} Please feel free to post any questions or suggestions as comments or in the forums, most of these features are the direct result of your feedback. JuanC
  21. Please note that by using format-table as the last element in your pipe, you are transforming the output into a table and although on the console it looks like the right data, properties are buried deep into the output, e.g. In a folder with a couple of CSV files type the following command dir *.csv | get-member You will see many properties and methods supported by the System.IO.FileInfo object, this means that potentially any of the numerical properties could be charted and any string properties could be used as labels. Now type the following dir *.csv | ft Length,Name | get-member Now instead of the 2 properties you will see a bunch of Internal objects like FormatStartData, GroupStartData, etc. none of these objects will show Length or Name as properties. You have 2 options to get the chart you want 1) Use select-object (select) instead of format-table (ft) get-exchangeserver | where-object {$_.IsHubTransportServer -eq $True} | get-queue | select {$_.Identity.ToString()}, MessageCount | out-chart[edit]Note that because Identity is a complex object you want to use ToString() in the select cmdlet This cmdlet selects a subset of properties so that in the console the output looks similar to that of format-table but under the covers this cmdlet is doing a very different job. It is creating a new object that supports only the properties you selected, You can confirm this by typing dir *.csv | select Length,Name | get-member 2) use -values and -label in out-chart to specify the columns you want to use get-exchangeserver | where-object {$_.IsHubTransportServer -eq $True} | get-queue | out-chart -values MessageCount -label {$_.Identity}[edit]Note that because Identity is a complex object you want to use a scriptblock in the label parameter. You can also use Identity.ToString as in option 1. Regards, JuanC
  22. There was a bug in an interim PowerGadgets build that could exhibit the behavior you are describing (hang when using an expression like $_.), please send an email to support at powergadgets dot com and we will send you an updated build. JuanC
  23. From within EMS you should be able to add-pssnapin PowerGadgets 10,20,15 | out-chart Once this works you can start experimenting invoking exchange cmdlets and piping their results to out-chart/out-gauge/out-map JuanC
  24. $items = get-childitem $args foreach($item in $items) { if ($item -is [system.IO.DirectoryInfo]) { $obj = new-object System.Object add-member -inputobject $obj -membertype NoteProperty -Name Folder -value $item add-member -inputobject $obj -membertype ScriptProperty -Name Length -value { $elem = get-childitem $this.Folder.FullName -include *.* -recurse | measure-object -sum length; if ($elem -eq $null) {return 0;} else {return $elem.Sum;} } write-output $obj } } See this post for information on using this script and powergadgets drilldown JuanC
  25. To illustrate how you can drilldown into hierarchical data using PowerGadgets and PowerShell, we will try to build a map of any folder in your hard disk showing the total size of all its subdirectories. There are many full blown apps that do this but I hope that in the process you will learn a few PowerShell tricks and discover how to use drilldown in PowerGadgets. Let's start building the script that populates our gadget. My first try resulted in a script called get-size.ps1 which looks like this. I have a scripts folder on my machine and this folder was added to the Path environment variable. $items = get-childitem $args foreach($item in $items) { if ($item -is [system.IO.DirectoryInfo]) { add-member -inputobject $item -membertype ScriptProperty -Name Length -value { $elem = get-childitem $this.FullName -include *.* -recurse | measure-object -sum length; if ($elem -eq $null) {return 0;} else {return $elem.Sum;} } write-output $item } } The meat of the script is in the add-member call, we are adding a new property to the directoryinfo object called Length and its value is a script that when executed will return the size of all the files and subdirectories in it. Calculating the size of a folder is achieved by the following get-childitem $this.FullName -include *.* -recurse | measure-object -sum length This first approach has a big drawback, if you just execute get-foldersize the output will be identical to doing get-item, in order to see the result of the calculations you have to type get-foldersize | select Name,Length. The reason for this is how PowerShell outputs data to the console but it also reveals an interesting feature, if you execute both commands on a big folder you will notice that get-foldersize is quick while get-foldersize | Select Name,Length is actually doing the calculations. This means that our code will only be executed on demand. Lazy evaluation is not important for this particular script but it could be prove to be a valuable feature in other scripts. Let's tweak our script to make it easier to see its results $items = get-childitem $args foreach($item in $items) { if ($item -is [system.IO.DirectoryInfo]) { $obj = new-object System.Object add-member -inputobject $obj -membertype NoteProperty -Name Folder -value $item add-member -inputobject $obj -membertype ScriptProperty -Name Length -value { $elem = get-childitem $this.Folder.FullName -include *.* -recurse | measure-object -sum length; if ($elem -eq $null) {return 0;} else {return $elem.Sum;} } write-output $obj } } This new version of our script is a little more verbose - note that we are now creating an empty object and adding 2 properties to it - but if you just type get-foldersize you will get the results you are looking for. Note that we are adding a property called Folder and we are returning the DirectoryInfo object, we are lucky enough that its ToString method just returns the name but we have all the DirectoryInfo properties at our disposal. This is a good compromise between showing relevant information when simply typing the command but still allowing full access to all folder properties, e.g. the following command will give you the name, total size and attributes of all the subdirectories. get-foldersize | Select {$_.Folder.Name},Length,{$_.Folder.Mode} Now we are ready to start interacting our script with PowerGadgets, the obvious command foldersize | out-chart will give you a bar chart showing the subdirectories sizes but you will not see any meaningful labels. This is due to how out-chart decides which properties should be plotted (any numerical properties although the algorithm is a little more complex than this) and which properties can be considered labels (any string properties). Because we decided that our Folder property will contain the full DirectoryInfo object, out-chart decides that it cannot be used as the label. Clearly this is something we can improve in future versions. For now you have to type the following get-foldersize | out-chart -label Folder -value Length /TeamBlogImages/DrillDownpart1.Hierarchicaldata_E115/FolderSizeChart2.png Let's add drill down capabilities to this by using drilldown_parameter, this allows you to specify which parameter(s) to pass when drilling down, e.g. when you double click on a bar, in our case we want to pass the full name of the child subdirectory to our get-foldersize script so we will just say get-foldersize | out-chart -label Folder -value Length -drilldown_parameter {$_.Folder.FullName} If you execute this command in a folder with subdirectories you will notice that when you double click on a bar the chart refreshes to show the size of the subdirectories of the folder you clicked on. To get back to the previous chart you can right click on the background of the chart and select back. If you are using build 2585 or later you can even use your mouse back button to return to the previous chart. If you double click a folder with no subdirectories you will get "No Data Available". Obviously full blown apps can provide many more features for this problem, but getting an interactive gadget that shows subdirectory sizes recursively with only a 9-liner PowerShell script and the PowerGadgets cmdlet certainly sounds promising. There are several ways we can improve on the visualization of this gadget, a typical one would be to show folders with a specific condition -e.g. those bigger than 10MB in a different color. Note that the -condition_ parameter actually exposes many visual attributes so you can control the color used, whether point labels are visible, etc. get-foldersize | out-chart -label Folder -value Length -drilldown_parameter {$_.Folder.FullName} -condition {$_.Length -gt 10MB} -condition_Color DarkRed /TeamBlogImages/DrillDownpart1.Hierarchicaldata_E115/FolderSizeCondition_thumb5.png Up to this point everything I described here is officially supported so to make this blog post a little more valuable I would like to show a totally unsupported but nonetheless cool feature, squarified treemaps are sometimes used in this kind of scenarios as they are able to convey size comparisons in a way where screen real-state use is maximized. Even though PowerGadgets does not natively support this as a gallery type, it supports the concepts of gallery extensions, and one of the ones we wrote as a proof of concept is a treemap extension. To use this you need to check if ChartFX.WinForms.TreeMap.dll is present in your PowerGadgets folder. get-foldersize | out-chart -label Folder -value Length -drilldown_parameter {$_.Folder.FullName} -gallery treemap /TeamBlogImages/DrillDownpart1.Hierarchicaldata_E115/FolderSizeTreemap.png I hope this post will get you interested on what you can achieve when using drilldown, in a future post we will show how to drilldown to a different script and other drilldown features. JuanC
×
×
  • Create New...