Richard Siddaway at IT Knowledge Exchange answers a very basic question that many new PowerShell scripters run into - Once I create a function, how do I use it.
Most of my scripts end up being functions because I will eventually combine them into modules
My recent script
function get-logedonuser {
param (
[string]$computername = $env:COMPUTERNAME
)
Get-WmiObject -Class Win32_LogonSession -ComputerName $computername |
foreach {
$data = $_
$id = $data.__RELPATH -replace """", "'"
$q = "ASSOCIATORS OF {$id} WHERE ResultClass = Win32_Account"
Get-WmiObject -ComputerName $computername -Query $q |
select @{N="User";E={$($_.Caption)}},
@{N="LogonTime";E={$data.ConvertToDateTime($data.StartTime)}}
}
}
Prompted a comment about how could you run this script.
First off I would save it to a file – get-logedonuser.ps1
You can then either
(read more)
If you are running PowerWF, it is very easy to leverage a function you find on the internet. Simply paste the function into a script block in the workflow and then either call it from that script block or from elsewhere in your workflow.
4 weeks ago - link
@XCUD had another interesting chat the other day related to Hash Tables. He was going to blog about it, but he’s busy working on some very cool features for the next version of PowerWF.
Anyway, the question was, what is the easiest way to find the max value in a Hash table. We decided it was easiest to sort the hash table and then return the first value. Here is an example (albeit a silly one)
# Easiest way to get the max value from a hash table #
function get-HashMaxValue($hashTable)
{
return $hashTable.GetEnumerator() | sort value -Descending | select -First 1
}
# Let's try it out
$myHash = @{}
# Populate a hash table
get-Process c* | foreach-object -Process {$myHash.add($_.Name + $_.Id, $_.CPU)}
# Output the results
$myHash
# And call our function...
write-Output "`n`nAnd the Winner is..."
get-HashMaxValue $myHash
2 months ago - link
I was on a chat earlier today with one of our users. I’m not sure why, but he wanted to find a way to persist a Hash Table between PowerShell sessions. I was pretty sure the both Ed Wilson and Jeffery Hicks had addressed similar problems in the past, so I gave him links to their sites, but I figured there was probably a pretty easy way to do this. Here’s what I came up with as a basic premise:
PS C:\Users\jhofer> $myHash = @{“foo”=1;”ack”=2}
PS C:\Users\jhofer> $myHash
Name Value
—— ——-
foo 1
ack 2
PS C:\Users\jhofer> $myHash | Export-Clixml c:\myhash.xml
PS C:\Users\jhofer> $newHash = Import-Clixml C:\myhash.xml
PS C:\Users\jhofer> $newHash
Name Value
—— ——-
ack 2
foo 1
PS C:\Users\jhofer> $newHash.Keys
ack
foo
So basically, it looks like he could add a line like $myHash = Import-Clixml C:\myhash.xml to his profile so that it would load his hash each time he starts up PowerShell. He could then add a PowerShell function to that would add or update values in his hash table and then overwrite the xml file. Here’s the final version of what I would add to the profile to accomplish this:
$global:persistentHash = @{}
$global:persistentHash = import-Clixml c:\Public\persistentHash.xml
function update-PersistentHash($key, $value)
{
if($global:persistentHash.Contains($key))
{
$global:persistentHash.Remove($key)
}
$global:persistentHash.Add($key,$value)
$global:persistentHash | export-Clixml c:\Public\persistentHash.xml -Force
}
2 months ago - link
I saw a question on StackOverflow the other day asking how to save PowerShell results as XML. If you are lucky, this could be as simple as using the export-clixml cmdlet.
But what if you are doing something more complex where you are pulling data from multiple sources or you want to control every aspect of the structure of the XML you are creating. In that case, I think you have 2 options.
The simplest way would be to build up a string as your xml -
$procs = get-Process
$xml = "<xml>`r`n"
foreach($proc in $procs)
{
$xml += "<process name='" + $proc.Name + "' id='Proc_"+$proc.Id+"'>`r`n"
$xml += "<modules>`r`n"
foreach($module in $proc.Modules)
{
$xml += "<module>"
$xml += $module.ModuleName
$xml += "</module>`r`n"
}
$xml += "</modules>`r`n"
$xml += "</process>`r`n"
}
$xml += "</xml>`r`n"
$xml | out-File -FilePath c:\temp\proc1.xml
The downside of this approach is that you need to build in you are reinventing the wheel and will therefore be responsible for any error checking and insuring that your final document is well formatted XML.
In many cases, a better way would be to build up your output as psobject/arrays/hashtables/etc. You can then use the PowerShell cmdlets for additional massaging if necessary and use the export-clixml to output it as XML. That would look something like this -
$procs = get-Process
$processObject = @()
foreach($proc in $procs)
{
$procInfo = new-Object PSObject
$procInfo | add-Member NoteProperty -Name "Process" $proc.Name
$procInfo | add-Member NoteProperty -Name "ID" $proc.Id
$moduleInfo = @()
foreach($module in $proc.Modules)
{
$moduleInfo += $module.ModuleName
}
$procInfo | add-Member NoteProperty -Name "Module" $moduleInfo
$processObject += $procInfo
}
$processObject | export-Clixml c:\temp\procs.xml
2 months ago - link
I have always had a - love - hate - despise - relationship with irregular regular expressions. PowerShell.com has a nice primer that can at least get you started on what will likely be one of the most fulfilling and frustrating relationships of your scripting life.
It starts with the basics of defining and explaining a regular expression pattern, and quickly shows you the power (and the frustrating nature) of working with them. The article also shows you several ways to do regular expressions within PowerShell.
The name of the article indicates that this may be part of a series. If the follow-ups add a lot of value, I’ll let you know.
3 months ago - link
Had a chat on the website today where someone asked -
How do I tell what version of PowerSE I have installed; it doesn’t have a help -> About
It turns out, the way to tell the version of PowerSE is the same way you would tell the version of PowerShell. From the embedded host in PowerSE, type this command:
PS C:> get-host
Name : PowerSE
Version : 2.5.3.502
InstanceId : cfc064c2-0958-41e5-bdd5-f3a35f7dfb98
UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture : en-US
CurrentUICulture : en-US
PrivateData : PoshConsole.PoshHostProxy
IsRunspacePushed : False
Runspace : System.Management.Automation.Runspaces.LocalRunspace
4 months ago - link
Organizing The Toolbox
The toolbox initially displays all of the activity packs that are installed for PowerWF Studio in alphabetical order. Although each pack contains useful activities, users undoubtedly find themselves using some packs more than others and some not at all. PowerWF allows activity packs to be arranged in any order or hidden from view.
Using Search
The easiest way to find activities is to use the search bar at the top of the toolbox. Type the first few letters of the search term and PowerWF will start filtering the list to only activities that match the search. PowerWF maintains the organization by grouping of activities in their respective activity packs.

Moving Activity Packs
To move an activity pack, drag the heading up or down in the toolbox.

Hiding Activity Packs
To hide one or more activity packs, right click on the activity pack heading and select either Hide or Hide All. See “Showing Activity Packs” for information on displaying hidden activity packs.

Showing Activity Packs
To show activity packs that have been hidden, right click anywhere in the toolbox and select Show or Show All.

2 years ago - link
PowerWF Studio allows multiple workflows to be open at one time to allow easy copy and paste between workflows. The easiest way to work with multiple workflows is to create multiple tab groups. This is done by clicking and dragging the workflow tab to the edge of the canvas.

Dragging the workflow to the right edge tells PowerWF that a new vertical tab group should be created. Once multiple tab groups are opened, activities can be moved from one workflow to another by selecting and dragging. To copy activities, hold down the CTRL key while dragging the activities.

PowerWF Studio supports standard features, such as SHIFT – CLICK or CTRL – CLICK to multi-select workflow activities. Holding down SHIFT while pressing down the left mouse button and then dragging allows the rubber-banding of multiple activities.

Right-click on an activity or group of activities to Cut, Copy, Paste, or Delete those activities. Activities can be copied from one workflow to another or within the same workflow.

2 years ago - link
This tutorial is the first in a series of tutorials on portable workflows; executing workflows outside of PowerWF Studio.
Regardless of the complexity of the workflow that is created, the workflow needs to be portable so it can be used outside PowerWF. PowerWF Studio allows workflows to be deployed a number of different ways. This tutorial will take the HelloWorld workflow and show how it can be deployed and run from as a console application.
Topics Discussed
- Deploying a workflow to run from a console
- Setting Help Text for input parameters
Procedure
- Open the HelloWorld workflow from the previous tutorial.

- When the HelloWorld workflow was created, Help Text was not added. Help Text instructs a user of the purpose of an input parameter. Click on the Parameters button and enter the Help Text, “Enter the text to be displayed in the message box.” Click OK.

- On the “Deploy” tab, click the “Console” button on the ribbon bar.

- PowerWF Studio will show the currently selected Workflow, as well as prompt for an executable name and output directory. Note the output directory, and then click OK to accept the defaults.

Note: The workflow can be executed immediately, but in this case that is not necessary.
- The workflow can now be launched as a command line application by opening a command prompt and navigating to the output directory. The workflow application will be in a subdirectory named “HelloWorld”. Enter “HelloWorld -?” to see how to use the application.

- To launch the application, type: HelloWorld –outputText=“a man a plan a canal panama”

Summary
This tutorial showed how to create a console application from an existing workflow. Help Text for Input Parameters was also briefly discussed. Subsequent tutorials will discuss other forms of portable workflows.
2 years ago - link
If you have to explain a process or script to someone, you will likely end up drawing them a picture to explain the process. If your process or script is already a PowerWF Workflow, you can simply click the “Save” button and select “Save as Image” to get a representation of your workflow that you can email or include in a document or presentation.

Glancing at this workflow, it is pretty easy to tell what it does:

Just reading the names of the activities, it should be obvious that the workflow gets a list of processes where something is special about them and sets a variable based on the results. It then checks some condition, and if that condition is met it starts a process. Finally it opens a VM, powers it on, and logs into the guest.
- PowerWF supports outputting the workflow as a PNG, JPG, BMP, TIFF, WMF, EXIF, and EMF
2 years ago - link
:::