Diazer
asked on
powershell INF compare.
I am trying to build a query that will go in a compare two inf files that may have different delimiters so that I can then create a table and display it by converting it to an HTML file.
Any ideas? The files that I am trying to compare are created by secedit.exe when the local group policy is exported..
I am able to compare the files when its X = Y but when it starts going x=y,z thats where I get lost..
I found this function and maybe thought it could be made to work for my needs..
regards,
Erica
GptTmpl.inf.txt
Any ideas? The files that I am trying to compare are created by secedit.exe when the local group policy is exported..
I am able to compare the files when its X = Y but when it starts going x=y,z thats where I get lost..
I found this function and maybe thought it could be made to work for my needs..
Function Get-IniContent
{
<#
.Synopsis
Gets the content of an INI file
.Description
Gets the content of an INI file and returns it as a hashtable
.Notes
Author : Oliver Lipkau <oliver@lipkau.net>
Blog : http://oliver.lipkau.net/blog/
Date : 2010/03/12
Version : 1.0
#Requires -Version 2.0
.Inputs
System.String
.Outputs
System.Collections.Hashtable
.Parameter FilePath
Specifies the path to the input file.
.Example
$FileContent = Get-IniContent "C:\myinifile.ini"
-----------
Description
Saves the content of the c:\myinifile.ini in a hashtable called $FileContent
.Example
$inifilepath | $FileContent = Get-IniContent
-----------
Description
Gets the content of the ini file passed through the pipe into a hashtable called $FileContent
.Example
C:\PS>$FileContent = Get-IniContent "c:\settings.ini"
C:\PS>$FileContent["Section"]["Key"]
-----------
Description
Returns the key "Key" of the section "Section" from the C:\settings.ini file
.Link
Out-IniFile
#>
[CmdletBinding()]
Param(
[ValidateNotNullOrEmpty()]
[ValidateScript({(Test-Path $_) -and ((Get-Item $_).Extension -eq ".inf")})]
[Parameter(ValueFromPipeline=$True,Mandatory=$True)]
[string]$FilePath
)
Begin
{Write-Verbose "$($MyInvocation.MyCommand.Name):: Function started"}
Process
{
Write-Verbose "$($MyInvocation.MyCommand.Name):: Processing file: $Filepath"
$ini = @{}
switch -regex -file $FilePath
{
"^\[(.+)\]$" # Section
{
$section = $matches[1]
$ini[$section] = @{}
$CommentCount = 0
}
"^(;.*)$" # Comment
{
if (!($section))
{
$section = "No-Section"
$ini[$section] = @{}
}
$value = $matches[1]
$CommentCount = $CommentCount + 1
$name = "Comment" + $CommentCount
$ini[$section][$name] = $value
}
"(.+?)=(.*)" # Key
{
if (!($section))
{
$section = "No-Section"
$ini[$section] = @{}
}
$name,$value = $matches[1..2]
$ini[$section][$name] = $value
}
}
Write-Verbose "$($MyInvocation.MyCommand.Name):: Finished Processing file: $path"
Return $ini
}
End
{Write-Verbose "$($MyInvocation.MyCommand.Name):: Function ended"}
}
regards,
Erica
GptTmpl.inf.txt
So have you tried something like compare-object (Get-IniContent A.ini) (Get-IniContent B.ini)?
ASKER
bepsoccer1,
When I type that it does nothing..
With the above script I can get it to add the values to a hash table, sort them and see there values but when it comes to comparing them is when I get lost..
Regards,
Erica
When I type that it does nothing..
With the above script I can get it to add the values to a hash table, sort them and see there values but when it comes to comparing them is when I get lost..
Regards,
Erica
When you say it does nothing you mean it gives no output? Generally that means they are the same. I don't know enough about the Get-INIContent function here, but just for more info does compare-object (Get-IniContent A.ini) (Get-IniContent B.ini) -includeEqual produce any results?
ASKER
I checked with windiff and they are not the same.. so I am at a loss.
are you just trying to identify the differences? If so, check out Beyond Compare, http://www.scootersoftware .com/downl oad.php?c= kb_morerul es
ASKER
I know that there are many utilities but what I am doing is going to compare the attached INF file as the base with a Unknown Inf file and then pipe the differences into an HTML file and this has to be done with little user internventions, I know that software exists out there but I also know that there has to be a way to put it data in an array or hashtable to compare it..
The issue is that the hash table again contains hash tables. Compare-Object cannot compare that, it can't even compare hash tables, AFAIK. So we have to "flatten" that to something we can compare:
function flatten-hash ($hash)
{ foreach ($section in $hash.keys)
{ foreach ($key in $hash[$section].keys)
{ foreach ($value in $hash[$section][$key])
{ New-Object PSObject -Property @{section = $section; key = $key; value = $value; String = "[$Section] $Key = $value" }
}}}}
$ini1 = flatten-hash (Get-IniContent GptTmpl.Inf)
$ini2 = flatten-hash (Get-IniContent GptReal.Inf)
Compare-Object -PassThru $ini1 $ini2 -Property String
That's not the best one can do, but should suffice to see differences.
ASKER
Qlemo,
Brilliant.. So how do I output that information to a HTML file?
Reason being is then I can do the Colorize and make things show up as the SideIndicator arrows just confuse the user.
Brilliant.. So how do I output that information to a HTML file?
Reason being is then I can do the Colorize and make things show up as the SideIndicator arrows just confuse the user.
The result of the compare contains the complete object (because of -PassThru, plus the side indicator. A common transformation is to have one object on the left, the other on the right, depending on the side indicator. That table can then be converted into HTML.
Compare-Object -PassThru $ini1 $ini2 -Property String | % {
if ($_.SideIndicator -eq "=>") { $obj = New-Object PSObject -Property @{LeftSection = $_.Section; LeftKey = $_.Key; LeftValue = $_.Value; RightSection = ""; RightKey = ""; RightValue = ""}}
if ($_.SideIndicator -eq "<=") {
if (!$obj) {
$obj = New-Object PSObject -Property @{LeftSection = ""; LeftKey = ""; LeftValue = ""; RightSection = $_.Section; RightKey = $_.Key; RightValue = $_.Value }
} else {
$obj.RightSection, $obj.RightKey, $obj.RightValue = $_.Section, $_.Key, $_.Value
}
$obj
}
} | select LeftSection, LeftKey, LeftValue, RightSection, RightKey, RightValue | ft
Again, that is not perfect, as it relies on the exact sequence as compare-object writes out differences. If you change one of the key names in GptReal.ini, you'll see.
ASKER
So the file would have to be exactiy the same as the other file sequence wise?
Do you know of a better method that would maybe put them in an array as the GptReal.inf is always going to be different computer to computer in some form or fasion.. I just want the most effective way of using SECedit.exe /export /cfg GptReal.inf getting that inf that is created from the export and comparing to known security values.. I would have been able to convert it to a csv and saved myself some headaches but I don't know how to use the delimiters in a way to convert "MACHINE\Software\Microsof t\Windows NT\CurrentVersion\Setup\Re coveryCons ole\Securi tyLevel=4, 0" to a comma seperated table which would be even better honestly.. Go line by line thru the Inf and then convert it to look like "MACHINE\Software\Microsof t\Windows NT\CurrentVersion\Setup\Re coveryCons ole\Securi tyLevel,4, 0
I guess if I went in the document and replaced all the = with commas that would work would it not? maybe I'm going about this the hard way.. LOL
Do you know of a better method that would maybe put them in an array as the GptReal.inf is always going to be different computer to computer in some form or fasion.. I just want the most effective way of using SECedit.exe /export /cfg GptReal.inf getting that inf that is created from the export and comparing to known security values.. I would have been able to convert it to a csv and saved myself some headaches but I don't know how to use the delimiters in a way to convert "MACHINE\Software\Microsof
I guess if I went in the document and replaced all the = with commas that would work would it not? maybe I'm going about this the hard way.. LOL
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you so much for your rapid response. I'm sure I will be calling on you for more questions.. :)
ASKER
I have been playing with the code but I still cant seem to get the tables to output into an HTML table.. I'm wanting a table that shows key and value. So it could list all the key's that are in the GptTmpl.inf, The Values with the column name "Default" and another colomn "Actual" that shows the current setting even if it is empty to show "No Value"
So I guess it would look something like this
Keys | Default | Actual
MaximumPasswordAge | 90 | 60
It just makes it easier to report the changes..
So I guess it would look something like this
Keys | Default | Actual
MaximumPasswordAge | 90 | 60
It just makes it easier to report the changes..
ASKER
Qlemo,
I manged to get the code to export to html but I am having some issues with the data not exporting over.. as you said the data has to line up.. I tried to use the sort feature but that seem to not make a differance.. Really I think that the code needs to be tweaked a little more and I am working on it but doing circles :( can you test with the file I attached and maybe export your GptTMPL.inf on your machine and do a compare.. Really I only need to display the table as I have above.
Thank you in advance
I manged to get the code to export to html but I am having some issues with the data not exporting over.. as you said the data has to line up.. I tried to use the sort feature but that seem to not make a differance.. Really I think that the code needs to be tweaked a little more and I am working on it but doing circles :( can you test with the file I attached and maybe export your GptTMPL.inf on your machine and do a compare.. Really I only need to display the table as I have above.
Thank you in advance
We would need to perform exact matches, and some more logic, to get above format. Still thinking about how to do that ...
Does this one work as a base for HTML reports for you?
Compare-Object -PassThru $ini1 $ini2 -Property String | % { $obj = $null } {
if ($obj -and $obj.Section -eq $_.Section -and $obj.Key -eq $_.Key)
{
if ($_.SideIndicator -eq '<=') { $obj.Default = $_.Value } else { $obj.Value = $_.Value }
} else {
$obj
$obj = New-Object PSObject -Property @{Section = $_.Section; Key = $_.Key; Default = $_.Value*($_.SideIndicator -eq '<='); Value = $_.Value*($_.SideIndicator -eq '=>') }
}
} {$obj}
ASKER
ok so that is looking better but it still does not line up the Key values and when it displays it they only shows the data that corrosponds to the key so I guess the Key values are not merging up and then displaying the values for each..
Would seeing the code help any?
Would seeing the code help any?
I see - compare-object is too stupid to provide differences in correct sequence. We have to sort that output, too.
Compare-Object -PassThru $ini1 $ini2 -Property String | sort String | % { $obj = $null } {
if ($obj -and $obj.Section -eq $_.Section -and $obj.Key -eq $_.Key)
{
if ($_.SideIndicator -eq '<=') { $obj.Default = $_.Value } else { $obj.Value = $_.Value }
} else {
$obj
$obj = New-Object PSObject -Property @{Section = $_.Section; Key = $_.Key; Default = $_.Value*($_.SideIndicator -eq '<='); Value = $_.Value*($_.SideIndicator -eq '=>') }
}
} {$obj}
This worked against my secedit export, which is totally different from your template, and so I'm confident it is what you need.
ASKER
do you know of any way to prevent this? maybe there is a way to merge the keys together?
Key Default Value
AuditAccountLogon 3
AuditAccountLogon 3
I'm looking into it as well as I'm sure its just another switch.. I know that we had it working the right way when importing the differnt CSV's
Key Default Value
AuditAccountLogon 3
AuditAccountLogon 3
I'm looking into it as well as I'm sure its just another switch.. I know that we had it working the right way when importing the differnt CSV's
Is it the same section? As long as both section and key are the same, you should only get a single entry. That worked great for me, as already said. Please check if there are no additional spaces in section or key or such (unlikely, but who knows?).
ASKER
It Works. had spaces in the INf File..
Thank you so much :)
Thank you so much :)
ASKER
Qlemo,
I am going to post another question and reference this one. as I am needing help with the hash table and I know you helped me before. I want you to get credit for it.
Erica
I am going to post another question and reference this one. as I am needing help with the hash table and I know you helped me before. I want you to get credit for it.
Erica