Working with text output

I’m trying to pull some output from a text file generated by HPBiosConfig tool. The plan is to run the tool and generate a text file with all the settings, pull out the 15 I’ve been asked to check and write each one as a registry property. Then from SCCM create a MOF file to generate a report.

I’m trying to manipulate the text.

here is a cut of the output from the HP tool:

BIOSConfig 1.0
;
;     Originally created by BIOS Configuration Utility
;     Version: 4.0.15.1
;     Date="2016/09/21" Time="20:16:41" UTC="1"
;
;     Found 229 settings
;
Manufacturer
	Hewlett-Packard
Product Name
	HP EliteBook 840
System Board ID
	2216
Processor Type
	Intel(R) Core(TM) i5-5300U CPU
Warranty Start Date
	00/00/0000
Processor Speed
	 2.30GHz
Sunday
	*Disable
	Enable
Monday
	*Disable
	Enable
Tuesday
	*Disable
	Enable
Wednesday
	*Disable
	Enable
Thursday
	*Disable
	Enable
Friday
	*Disable
	Enable
Saturday
	*Disable
	Enable
BIOS Power-On Time (hh:mm)
	00:00
PCID Version
	A3.00
HDD Model
	Crucial_CT750MX300SSD1                  
HDD Size
	750 GB
Total Memory Size
	16384 MB
Memory Slot 1 Information
	Bottom-Slot 1(left) 1315 8192 MB @ 1600 MHz
Memory Slot 2 Information
	Bottom-Slot 2(right) 1315 8192 MB @ 1600 MHz
Define Customized Boot Option
Secondary Battery Serial Number
	No Battery Present
Flash media reader
	Disable
	*Enable
USB Port
	Disable
	*Enable
Smart Card
	Disable
	*Enable
WWAN FCC ID
	No Device Present
WLAN FCC ID
	PD97265NG
Bluetooth FCC ID
	PD97265NG
Product Family
	103C_5336AN G=N L=BUS B=HP S=ELI
GPS FCC ID
	No Device Present

by doing this I can find the Manufacturer

 gc .\all.txt | select-string “Manufacturer” -Context 0,1 

but its displayed as :

> Manufacturer
  	Hewlett-Packard

How can I join these two lines together, ideally like “Manufacturer = Hewlett-Packard”

Looking to expand my knowledge in this area, so any advice would be great. I need to check 340 pc’s and they need the bios to have the same settings. I need to generate a report with the mismatches.

PowerShell is not always aces for string manipulation, but in this case you should be OK. What you’ve got to do is replace the carriage return and maybe some spaces, with an = sign. So assuming $x has your 2 line output…

$lines = $x -split “\n” # this might need to be \r\n
$final = “$($lines[0].Trim()) = $(lines[1].Trim())”

I’d probably have to play with that a bit to nail the exact thing, but that’s one approach. You’re splitting on the carriage return, giving you a two-element array. I then trim white space off each element as I combine them together with a = in between.

Look at the System.String documentation in MSDN. Lots of good string manipulation stuff, there.

Here is one option. Not to complex. Basically, if the line does not start with a tab, we consider it a property. If there is a tab, it’s a value. A little more logic for the Enable\Disable asterick stuff and we get a object with all properties:

$file = Get-Content C:\Users\Rob\Desktop\Archive\test.txt | Select -Skip 8

$props = @{}
foreach ($line in $file) {
    # line doesn't contain a tab, consider it a Property
    if ($line -notlike "`t*") {
        #"Property: {0}" -f $line
        $property = $line 
        $value = $null
        continue   
    }
    else {
       if ($line -like "*able") {
            if ($line -match "\*") {
               #"Value: {0}" -f $line -replace "\t\*", "" 
               $value = $line -replace "\t\*", ""
            }
            else {
                #"Skip value {0}" -f $line
                continue
            }
        }
        else {
            #"Value: {0}" -f $line -replace "\t", ""
            $value = $line -replace  "\t", ""
        }        
    }
    #if ($value) {"{0} : {1}" -f $property, $value}
    if ($value) {$props.Add($property, $value)}
}

$results = @()
$results += New-Object -TypeName PSObject -Property $props

$results

Output:

Tuesday                         : Disable
Warranty Start Date             : 00/00/0000
HDD Size                        : 750 GB
Product Family                  : 103C_5336AN G=N L=BUS B=HP S=ELI
Processor Speed                 :  2.30GHz
Secondary Battery Serial Number : No Battery Present
Wednesday                       : Disable
Memory Slot 2 Information       : Bottom-Slot 2(right) 1315 8192 MB @ 1600 MHz
Product Name                    : HP EliteBook 840
WWAN FCC ID                     : No Device Present
Bluetooth FCC ID                : PD97265NG
PCID Version                    : A3.00
GPS FCC ID                      : No Device Present
USB Port                        : Enable
Processor Type                  : Intel(R) Core(TM) i5-5300U CPU
Total Memory Size               : 16384 MB
System Board ID                 : 2216
BIOS Power-On Time (hh:mm)      : 00:00
Friday                          : Disable
Flash media reader              : Enable
Saturday                        : Disable
WLAN FCC ID                     : PD97265NG
Monday                          : Disable
Manufacturer                    : Hewlett-Packard
Smart Card                      : Enable
Sunday                          : Disable
Thursday                        : Disable
Memory Slot 1 Information       : Bottom-Slot 1(left) 1315 8192 MB @ 1600 MHz
HDD Model                       : Crucial_CT750MX300SSD1

Hey,

another approach could be this:

$Content = gc .\all.txt | select-string “Manufacturer” -Context 0,1
$Content.Matches.Value ,$Content.Context.DisplayPostContext.trim() -join " = "

Thanks for those great replies. I’ll have a play today, but great to see and learn some different techniques. I’ll be sure to look at the msdn documentation as well Don.

Rob, i really like how your example works. I’ve been playing around and can’t seem to work out how I can group a property which has more than one value. So for example, ‘Bios Order’ has several values, how could i display these like,

Boot Order : Boot1
Boot2
Boot3

I know i can’t add this to an array or hashtable, and can capture the output in a variable, which is a string.

You could convert the values into an array, like so:

$file = Get-Content C:\Users\Rob\Desktop\Archive\test.txt | Select -Skip 8

$props = @{}
foreach ($line in $file) {
    # line doesn't contain a tab, consider it a Property
    if ($line -notlike "`t*") {
        #"Property: {0}" -f $line
        $property = $line 
        if ($value) {$props.Add($property, $value)}
        $value = $null
    }
    else {        
        if (!$value) {
            [string]$value = $line -replace "\t", ""
        }
        else {
            [array]$value += $line -replace "\t", ""
        }        
    }    
}

$results = @()
$results += New-Object -TypeName PSObject -Property $props

$results

Output:

Tuesday                       : {*Disable, Enable}
Warranty Start Date           : Intel(R) Core(TM) i5-5300U CPU
HDD Size                      : Crucial_CT750MX300SSD1                  
Product Family                : PD97265NG
Processor Speed               : 00/00/0000
Sunday                        :  2.30GHz
Wednesday                     : {*Disable, Enable}
Memory Slot 2 Information     : Bottom-Slot 1(left) 1315 8192 MB @ 1600 MHz
Product Name                  : Hewlett-Packard
WWAN FCC ID                   : {Disable, *Enable}
Bluetooth FCC ID              : PD97265NG
PCID Version                  : 00:00
GPS FCC ID                    : 103C_5336AN G=N L=BUS B=HP S=ELI
Define Customized Boot Option : Bottom-Slot 2(right) 1315 8192 MB @ 1600 MHz
USB Port                      : {Disable, *Enable}
Processor Type                : 2216
Smart Card                    : {Disable, *Enable}
Total Memory Size             : 750 GB
BIOS Power-On Time (hh:mm)    : {*Disable, Enable}
Friday                        : {*Disable, Enable}
Flash media reader            : No Battery Present
Saturday                      : {*Disable, Enable}
WLAN FCC ID                   : No Device Present
Monday                        : {*Disable, Enable}
Manufacturer                  : No Device Present
System Board ID               : HP EliteBook 840
Thursday                      : {*Disable, Enable}
Memory Slot 1 Information     : 16384 MB
HDD Model                     : A3.00

Rob,

Your a genius ! I’ve spent all morning on this.

One small snag…


Processor Type                                 : ASF
Network Service Boot                           : {Device hidden, *Device available}
Monday                                         : {*Disable, Enable}
ACPI S3 Hard Disk Reset                        : {Normal, *Extended}
SOL Character Echo                             : {*Disable, Enable}
Legacy Diskette                                : {Device hidden, *Device available}
Runtime Power Management                       : {*Enable, Disable}
Data Execution Prevention                      : 39166D1D9FD1E111BBDA0503F3BA24BE
SOL Terminal Emulation Mode                    : {*Disable, Enable}
Headless Mode                                  : {*Enable, Disable}
BIOS Power-On Time (hh:mm)                     : {*Disable, Enable}
Slot 2 - Compute                               : {*Enable, Disable}
SATA0                                          : {Device hidden, *Device available}
ACPI S3 PS2 Mouse Wake Up                      : {*Disable, Enable}
SATA Emulation                                 : {*Enable, Disable}
SATA1                                          : {Device hidden, *Device available}
Enter Ownership Tag                            : {Disable, *Enable}
Fan Idle Mode                                  : {*Disable, Enable}
Password Prompt on Warm Boot                   : {*Disable, Enable}
Num Lock State at Power-On                     : {*Enable, Disable}
Remote Wakeup Boot Source                      : {*Enable, Disable}
Legacy Diskette Write                          : {*Enable, Disable}
Virtualization Technology (VTx)                : {Disable, *Enable}
Slot 4 Option ROM Download                     : {*Disable, Enable}
NIC PXE Option ROM Download                    : {*Disable, Enable}
Internal Speaker                               : {*Enable, Disable}
AES Instructions                               : {Disable, *Enable}
Family Name                                    : PC88125
Hyper-Threading                                : {*None, 5, 10, 15...}
Slot 2 Option ROM Download                     : {*Disable, Enable}
Slot 1 - Compute                               : {*Enable, Disable}
Sunday                                         : {*Disable, Enable}
POST Delay (in seconds)                        : {*Off, On, Previous State}
SATA PORT 0                                    : {*IDE, --, RAID+AHCI, --}
Enter UUID                                     :                                                                                 
Slot 3 - Compute                               : {*Enable, Disable}
Slot 6 Option ROM Download                     : {*Disable, Enable}
Virtualization Technology Directed I/O (VT-d2) : {Disable, *Enable}
F10 Prompt                                     : {*Displayed, Hidden}
Controller Order                               : {Optical Drive, USB device, Hard Drive, Ethernet controller...}
PCI SERR# Generation                           : 00:00
Idle Power Savings                             : {Disable, *Enable}
Slot 6 Latency Timer                           : {*Enable, Disable}
F9 Prompt                                      : {Enable, *Disable}
SATA PORT 3                                    : {*GEN2/3.0Gbps (Internal Only), GEN2/3.0Gbps (eSATA), GEN1/1.5Gbps (Internal Only), GEN1/1.5Gbps (eSATA)}
Friday                                         : {*Disable, Enable}
SOL Local Keyboard                             : {*VT100, ANSI}
SATA PORT 5                                    : {*GEN2/3.0Gbps (Internal Only), GEN2/3.0Gbps (eSATA), GEN1/1.5Gbps (Internal Only), GEN1/1.5Gbps (eSATA)}
Wednesday                                      : {*Disable, Enable}
Removable Media Boot                           : 384KB / 1536KB / 12MB
PCI VGA Palette Snooping                       : {Disable, *Enable}
System Audio                                   : {*Device available, Device hidden}
Enhanced Intel Turbo Boost Technology          : {Disable, *Enable}
SATA2                                          : {Device hidden, *Device available}
SATA PORT 1                                    : {*GEN2/3.0Gbps (Internal Only), GEN2/3.0Gbps (eSATA), GEN1/1.5Gbps (Internal Only), GEN1/1.5Gbps (eSATA)}
SATA4                                          : {Device hidden, *Device available}
Saturday                                       : {*Disable, Enable}
Slot 5 Option ROM Download                     : {*Disable, Enable}
Enhanced Memory Performance                    : {*Disable, Enable}
After Power Loss                               : {Remote Server, *Local Hard Drive}
Front USB ports                                : {*Enable, Disable}
Setup Browse Mode                              : {*Disable, Enable}
USB Wake on Device Insertion                   : {Disable, *Enable}
SATA PORT 2                                    : {*GEN2/3.0Gbps (Internal Only), GEN2/3.0Gbps (eSATA), GEN1/1.5Gbps (Internal Only), GEN1/1.5Gbps (eSATA)}
Option ROM Prompt                              : {*Displayed, Hidden}
Unique Sleep State Blink Rates                 : {*Disable, Enable}
SATA PORT 4                                    : {*GEN2/3.0Gbps (Internal Only), GEN2/3.0Gbps (eSATA), GEN1/1.5Gbps (Internal Only), GEN1/1.5Gbps (eSATA)}
Monitor Tracking                               : {Disable, *Enable}
Slot 3 Option ROM Download                     : {*Disable, Enable}
Processor Stepping                             : 3333/6400 MHz
Active Cores                                   : {*Enable, Disable}
SATA3                                          : {Device hidden, *Device available}
SATA5                                          : {Device hidden, *Device available}
Processor Speed                                : Intel(R) Xeon(R) CPU W3680 @ 3.33GHz
POST Messages                                  : {*+------, ++-----, +++----, ++++---...}
Slot 5 Latency Timer                           : {*Enable, Disable}
System BIOS                                    : 18432 MB
Memory Size (Total)                            : HP Z400 Workstation (VS933AV)
Intel Turbo Boost Technology                   : {Disable, *Enable}
Chassis Serial Number                          : 786G3 v03.54
Tuesday                                        : {*Disable, Enable}
Network Server Mode                            : {Integrated SATA, Integrated SATA RAID, Boot Device #2, Boot Device #3...}
Multi-Processor                                : {*Enable, Disable}
Cache Size (L1/L2/L3)                          : 000206C2 00000013
F12 Prompt                                     : {*Displayed, Hidden}
Slot 4 - Compute                               : {*Enable, Disable}
Slot 5 - Compute                               : {*Default, 32 PCI Clocks, 64 PCI Clocks, 96 PCI Clocks...}
IEEE 1394 Controller                           : {Device hidden, *Device available}
EUP Compliance Mode                            : {*Disable, Enable}
Management Mode                                : 103C_53335X
Ethernet controller                            : {Device hidden, *Device available}
Rear USB ports                                 : {*Device available, Device hidden}
Internal USB ports                             : {*Device available, Device hidden}
Slot 1 Option ROM Download                     : {*Disable, Enable}
SATA Power Management                          : {*Disable, Enable}
Asset Tracking Number                          : CZC2293KHV
S5 Wake on LAN                                 : {Off, *On}
Limit CPUID Maximum Value to 3                 : {*All Cores, 2 Cores, 1 Core}
Thursday                                       : {*Disable, Enable}
Password prompt on F9, F11, & F12              : {Disable, *Enable}
Boot Order                                     : {*GEN2/3.0Gbps (Internal Only), GEN2/3.0Gbps (eSATA), GEN1/1.5Gbps (Internal Only), GEN1/1.5Gbps (eSATA)}
BIOSConfig 1.0                                 : {*Disable, Enable}
Slot 6 - Compute                               : {*Default, 32 PCI Clocks, 64 PCI Clocks, 96 PCI Clocks...}
MWAIT-Aware OS                                 : {Disable, *Enable}

For the boot order and Sata Port’s its displaying the same result…

Hi Rob,

So its working but putting them in the incorrect order.

One thing i’m trying to get my head around, if i add a $value variable after $property = $line its populated with what doesn’t have a carriage … but that variable is not defined. How is it getting created ?

$file = Get-Content C:\Users\Rob\Desktop\Archive\test.txt | Select -Skip 8

$props = @{}
foreach ($line in $file) {
    # line doesn't contain a tab, consider it a Property
    if ($line -notlike "`t*") {
        #"Property: {0}" -f $line
        $property = $line 
   
    ### I've added Rob ####     
        $value    
        if ($value) {$props.Add($property, $value)}
        $value = $null
    }
    else {        
        if (!$value) {
            [string]$value = $line -replace "\t", ""
        }
        else {
            [array]$value += $line -replace "\t", ""
        }        
    }    
}

$results = @()
$results += New-Object -TypeName PSObject -Property $props

$results

Thanks Rob :slight_smile:

Had the line in the wrong place, it has to be above the property line:

$file = Get-Content C:\Users\Rob\Desktop\Archive\test.txt | Select -Skip 8

$props = @{}
foreach ($line in $file) {
    if ($line -notlike "`t*") {
        if ($value) {$props.Add($property, $value)}      

        $property = $line 
        $value = $null
    }
    else {        
        if (!$value) {
            [string]$value = $line -replace "\t", ""
        }
        else {
            [array]$value += $line -replace "\t", ""
        }        
    }    
}

$results = @()
$results += New-Object -TypeName PSObject -Property $props

$results

If you walk thru the loop sequence…
Loop 1
Manufacturer does not start with a tab
Value doesn’t exist (or is null), so skip hashtable add
Set Manufacturer as Property
Loop 2
Hewlett-Packard does start with tab
Set Property string as Hewlett-Packard
Loop 3 (We’ll pretend this is Sunday)
Sunday does not start with a tab
Value is not null (we set it in Loop 2), add our first Property and Value to the hashtable
Set Sunday as Property
Loop 4

Next 2 loops have tabs, so we add them to an array and so on and so forth. Don’t know it’s the ‘best’ way to do it, but I think a regex grouping pattern, if possible, would look like Matrix code and would really difficult to read.

One thing i’m trying to get my head around, if i add a $value variable after $property = $line its populated with what doesn’t have a carriage … but that variable is not defined. How is it getting created ?

That’s brilliant Rob, i’ve learnt something there so i’m grateful. Can i add in the part to only show the *able on those options easily ?

If you only care about what is select with the asterick, you could do something like this:

$file = Get-Content C:\Users\Rob\Desktop\Archive\test.txt | Select -Skip 8

$props = @{}
foreach ($line in $file) {
    if ($line -notlike "`t*") {
        
        if ($value) {
            #if there is more than one value, only get the one with an asterick
            if ($value -is [array]) {[string]$value = $value | Where{$_ -match "\*"} | foreach{$_.Replace("*","")}}
            $props.Add($property, $value)
        }      

        $property = $line 
        $value = $null
    }
    else {        
        if (!$value) {
            [string]$value = $line -replace "\t", ""
        }
        else {
            [array]$value += $line -replace "\t", ""
        }        
    }    
}

$results = @()
$results += New-Object -TypeName PSObject -Property $props

$results

Output:

Warranty Start Date             : 00/00/0000
HDD Size                        : 750 GB
Product Family                  : 103C_5336AN G=N L=BUS B=HP S=ELI
Processor Speed                 :  2.30GHz
Secondary Battery Serial Number : No Battery Present
Wednesday                       : Disable
Tuesday                         : Disable
Product Name                    : HP EliteBook 840
WWAN FCC ID                     : No Device Present
Bluetooth FCC ID                : PD97265NG
PCID Version                    : A3.00
GPS FCC ID                      : No Device Present
USB Port                        : Enable
Processor Type                  : Intel(R) Core(TM) i5-5300U CPU
Total Memory Size               : 16384 MB
System Board ID                 : 2216
BIOS Power-On Time (hh:mm)      : 00:00
Friday                          : Disable
Flash media reader              : Enable
Saturday                        : Disable
WLAN FCC ID                     : PD97265NG
Memory Slot 2 Information       : Bottom-Slot 2(right) 1315 8192 MB @ 1600 MHz
Monday                          : Disable
Manufacturer                    : Hewlett-Packard
Smart Card                      : Enable
Sunday                          : Disable
Thursday                        : Disable
Memory Slot 1 Information       : Bottom-Slot 1(left) 1315 8192 MB @ 1600 MHz
HDD Model                       : Crucial_CT750MX300SSD1   

Also, if you are retentive like me, the Processor Speed had a rogue space, so you could Trim whitespace before\after values by doing this:

$props.Add($property, $value.Trim())

Awesome, such a help. Thanks ! What I’m after is for enable or disabled only show the the result marked with an * but keep the other results as normal… if thst makes sense !

If I understand, you want to extract the chosen value for Enable\Disable, but want other multi-value items to remain an array:

        if ($value) {
            if ($value -is [array] -and ($value -contains "Enable" -or $value -contains "Disable")) {
                [string]$value = $value | Where{$_ -match "\*"} | foreach{$_.Replace("*","")}
            }
            $props.Add($property, $value.Trim())
        }      

Output (see Test property):

Warranty Start Date             : 00/00/0000
HDD Size                        : 750 GB
Product Family                  : 103C_5336AN G=N L=BUS B=HP S=ELI
Processor Speed                 : 2.30GHz
Secondary Battery Serial Number : No Battery Present
Wednesday                       : Disable
Tuesday                         : Disable
Product Name                    : HP EliteBook 840
System Board ID                 : 2216
Bluetooth FCC ID                : PD97265NG
PCID Version                    : A3.00
GPS FCC ID                      : No Device Present
WWAN FCC ID                     : No Device Present
USB Port                        : Enable
Processor Type                  : Intel(R) Core(TM) i5-5300U CPU
Test                            : {Value1, Value2, *Value3}
Total Memory Size               : 16384 MB
BIOS Power-On Time (hh:mm)      : 00:00
Friday                          : Disable
Flash media reader              : Enable
Saturday                        : Disable
WLAN FCC ID                     : PD97265NG
Memory Slot 2 Information       : Bottom-Slot 2(right) 1315 8192 MB @ 1600 MHz
Monday                          : Disable
Manufacturer                    : Hewlett-Packard
Smart Card                      : Enable
Sunday                          : Disable
Thursday                        : Disable
Memory Slot 1 Information       : Bottom-Slot 1(left) 1315 8192 MB @ 1600 MHz
HDD Model                       : Crucial_CT750MX300SSD1

Rob you’ve been brilliant and very helpful. I’ve learnt sonething here today and I’m very grateful. Thanks again.

Rob, apologies…having a frustrating time here…I want to single out all Values which start with * but if they don’t (i.e. boot order) display the list. Trying to get my head around it this change…

$file = Get-Content "C:\Program Files (x86)\HP\BIOS Configuration Utility\all.txt" | Select -Skip 8

$props = @{}
foreach ($line in $file) {
    if ($line -notlike "`t*") {
        if ($value) {
            if ($value -is [array]) {
                [string]$value = $value | Where{$_ -match "\*"} | foreach{$_.Replace("*","")}
            }
            $props.Add($property, $value.Trim())
        }      

        $property = $line 
        $value = $null
    }

    else {        
        if (!$value) {
            [string]$value = $line -replace "\t", ""
        }
        else {
            [array]$value += $line -replace "\t", ""
        }        
    } 
       
}

$results = @()
$results += New-Object -TypeName PSObject -Property $props

$results

I thought by removing the “enable” and “Disable” part this would work. Not sure why this is not sinking in !

That is what I showed in https://powershell.org/forums/topic/working-with-text-output/#post-54448

But that also strips out the boot options and other items that don’t have an *

If it has a *, then i’m after that value but if it hasn’t display all options.

i.e.

Multi Core CPU : Enable
Boot Options : {Harddisk, USB, CD-rom etc)