#requires -version 2.0 <# ----------------------------------------------------------------------------- Script: Convert-TexttoObject.ps1 Version: 1.5 Author: Jeffery Hicks http://jdhitsolutions.com/blog http://twitter.com/JeffHicks http://www.ScriptingGeek.com Date: 1/11/2012 Keywords: Comments: "Those who forget to script are doomed to repeat their work." **************************************************************** * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED * * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF * * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, * * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. * **************************************************************** ----------------------------------------------------------------------------- #> Function Convert-TextToObject { <# .Synopsis Convert text to a PowerShell object .Description This function takes a collection of simple delimited lines and turns them into an object. The function assumes a single delimiter. The default delimiter is the colon (:). The item to the left will be the property and the item on the left will be the property value. By default the function will split on every delimiter, but you can use the -SplitCount parameter to control the number of strings. If you don't want to split at all use a value of 1. To split on the first delimiter only, use a value of 2. For example, if the string is: Foobar: 01/11/2012 09:41:28 and you tried to split on the ":", you would end up with 4 elements in the array. But using a -SplitCount value of 2 would give you this: Foobar 01/11/2012 09:41:28 Use $GroupCount to keep track of items that come in groups and write a new object when the count has been reached. For example, this allows you to pipe in a long collection of strings and turn every 5 into an object. This function works best with command line tools that write list-like output. .Parameter Text The text to be converted .Parameter Delimiter The text delimiter to split on. The colon (":") is the default. .Parameter SplitCount The number of strings to create when splitting. The default is to split on all delimiters. If you don't want to split at all use a value of 1. To split on the first delimiter only, use a value of 2. .Parameter GroupCount The number of piped in strings to group together to form a new object. .Example PS C:> tasklist /s server01 /fo list | where {$_} | convert-texttoobject -group 5 Take the output for Tasklist.exe as a list, strip out blank lines and pipe to Convert-TextToObject. Turn every 5 items into an object. .Example PS C:\> get-content c:\work\data.txt | select -skip 4 | where {$_} | cto -group 4 -SplitCount 2 | format-list LinkDate : 11/20/2010 5:44:56 AM DisplayName : 1394 OHCI Compliant Host Controller DriverType : Kernel ModuleName : 1394ohci LinkDate : 11/20/2010 4:19:16 AM DisplayName : Microsoft ACPI Driver DriverType : Kernel ModuleName : ACPI LinkDate : 11/20/2010 4:30:42 AM DisplayName : ACPI Power Meter Driver DriverType : Kernel ModuleName : AcpiPmi Get the Data.txt file, skipping the first 4 lines and stripping out blanks. Then create objects for every 4 lines. The SplitCount is set to 2 so that the LinkDate value is the complete datetime stamp. .Example PS C:\> whoami /user /fo list | where {$_ -match ":"} | convert-texttoobject | format-table -auto UserName SID -------- --- serenity\jeff S-1-5-21-2858895768-3673612314-3109562570-1000 .Example PS C:\> whoami /groups /fo list | where {$_ -match ":"} | cto -group 4 | format-list Attributes : Mandatory group, Enabled by default, Enabled group Type : Well-known group GroupName : Everyone SID : S-1-1-0 Attributes : Mandatory group, Enabled by default, Enabled group, Group owner Type : Alias GroupName : BUILTIN\Administrators SID : S-1-5-32-544 ... Get group listing from Whoami.exe and filter out lines that don't have a colon. Create objects for every 4 lines. This example is using the cto alias for the Convert-TexttoObject function. .Link about_Split New-Object .Inputs Strings .Outputs Custom object #> [cmdletbinding(SupportsShouldProcess=$True)] param ( [Parameter(Position=0,Mandatory=$True,HelpMessage="Enter a string to be parsed into an object", ValueFromPipeline=$True)] [ValidateNotNullorEmpty()] [string[]]$Text, [Parameter(Position=1)] [ValidateNotNullOrEmpty()] [string]$Delimiter=":", [ValidateScript({$_ -ge 0})] [int]$SplitCount=0, [int]$GroupCount ) Begin { Write-Verbose "Starting $($myinvocation.mycommand)" #define a hashtable $myHash=@{} if ($GroupCount) { Write-Verbose "Grouping every $GroupCount items as an object" } #start an internal counter $i=0 Write-Verbose "Skipping $Skip lines" Write-Verbose "Using $Delimiter delimiter" Write-Verbose "Splitting into $SplitCount lines. 0 means all." } Process { Foreach ($item in $text) { if ($i -lt $GroupCount) { $i++ } else { #reset $i=1 } #split each line at the delimiter $data=$item -Split $delimiter,$SplitCount #remove spaces from "property" name $prop=$data[0].Replace(" ","") #trim $prop=$prop.Trim() $val=$data[1].Trim() #add to hash table Write-Verbose "Adding $prop to hash table with a value of $val" $myHash.Add($prop,$val) #if internal counter is equal to the group count #write the object and reset the hash table if ($i -eq $groupCount) { New-Object -TypeName PSObject -Property $myHash $myHash.Clear() } } #foreach } End { #create new object from hash table if ($myHash.count -gt 0) { New-Object -TypeName PSObject -Property $myHash Write-Verbose "Ending $($myinvocation.mycommand)" } } } #end function New-Alias -Name cto -Value Convert-TexttoObject