String handling

by matttilford at 2013-04-23 14:38:46

Ok, a quick bit of background. We have AutoDesk network licences that we can view the current usage of using a program called JTB FlexReport. I am using it to output a html file which i am then reading into powershell so i can see which program is using the licence (mainly Revit or AutoCAD) but also which version.

The html output is mostly a standard html table.

$ReportApp = "JTB FlexReport LT.exe"
$ReportAppOpt = "/h"
Start-Process $ReportApp $ReportAppOpt

sleep -seconds 10

$file = Get-Content "$env:localappdata/Temp/JTBFlexReportLT.htm" | select-string "@" | Select-String "td"
$file | ForEach-Object {
$out = $file -replace "<td nowrap>",""
$out = $out -replace "</td>",""
$out = $out -split "@"
}
$pclist =@()
$out | ForEach-Object {
if ($_ -match "PE-"){
$pclist += $
}
}

$pclist = $pclist | sort -Unique

$results = Invoke-Command -ComputerName $pclist -ScriptBlock {
Get-Process -Name Revit, Acad -FileVersionInfo | select -Property FileName
}
$results | Out-GridView


The split on the @ is because the result is given as username@computername, so then loop through the data to get the computer names. I also need to get the unique entries as each entry will be in at least twice: once for the version (i.e. BDS 2013) and once for the overall count.

What i’m mainly wondering is if there is a better way to handle the string? Most of the script is getting data from a line such as <td nowrap>abc@PE-PC-01</td>

Am i missing some obvious way of working with the string i’m given? Also my apologies for $
, i’m still working with some PS2 on Server 2003 so i’ve not moved to $PSItem yet.
by mjolinor at 2013-04-23 15:07:26
It would help to see the original string.
by poshoholic at 2013-04-23 21:04:52
Also, you don’t need to apologize for using $. :slight_smile:

t’s still supported, and the odds your scripts will run on both v2 and v3 go up when you use $
, and down when you use $PSItem. I’ll be using $_ for a long time yet.
by matttilford at 2013-04-24 02:25:14
Yeah i agree i wasn’t very clear in my original post. The Get-Content extracts the lines i need to work with i.e <td nowrap>abc@PE-PC-01</td>
What i’m looking at is the next 10 lines of code that are there just to extract the computer name from that string. Am i missing a trick or is that the best way to handle it?
by mjolinor at 2013-04-24 03:26:25
Try this:

$regex = '\s*<td nowrap>.+?@(.+)</td>\s*'

$pclist = (Get-Content "$env:localappdata/Temp/JTBFlexReportLT.htm") -match $regex -replace $regex,'$1'


The -match and -replace operators will work on both an array and on a scalar (single object). When you use -match against a single string, it returns True/False. If you use it against an array, it returns all the elements of the array that match. You can also chain those opertions together in a single command line.

The parens around the get-content will produce an array of all the lines, the -match filters out all the lines you don’t want, and the -replace gets rid of all the text you don’t want in the lines that did match.
by matttilford at 2013-04-24 09:03:43
You are a legend, not only does it work perfectly i even understand why! As an added bonus i piped that into sort -unique which got rid of another line.
by eisenbergz at 2013-04-24 22:36:04
Could you explain the $1 ? I don’t see where that object comes from. Thanks.
by matttilford at 2013-04-25 03:24:01
I had to quickly remind myself what it was, but i have used it before. Basically it’s the bit inside the brackets, so $0 is the whole string and $1 is the bit inside the first brackets. If i wanted to get the username from that string as well i could change the regex

$regex = ‘\s*<td nowrap>(.+?)@(.+)</td>\s*’
So then $1 would be the username and $2 would be the computer name.
by eisenbergz at 2013-04-25 05:12:33
Makes sense. Does that variable persist until the end of the script?

Matt,
Would you mind posting your completed script or emailing me a copy. We’re trying to do the same thing. Thanks

Randy, this post came from our old forums, so Matt won’t see your request. He’s at @matttilford on Twitter, if you’d like to try there.