Powershell- compare files and take action - powershell

I'm attempting to create a powershell script to compare two IP addresses out of two different text files then take an action base on if they match or they don't match. See below
(Invoke-WebRequest ifconfig.me/ip).content | Out-File "C:\test\test2.txt"
$ErrorActionPreference = "Stop"
$File = "C:\test\test.txt"
$File2 = "C:\test\test2.txt"
Compare-Object -ReferenceObject (Get-Content $File2) -DifferenceObject (Get-
Content $File) -IncludeEqual
If the two files match I obviously get a ==, or an => if they don't match. I'm not sure how to use == or => as a variable to continue the rest of the script. Any help or recommendations are greatly appreciated.

One way is to check the value of the SideIndicator property; e.g.:
if ( (Compare-Object (Get-Content test1.txt) (Get-Content test2.txt) -IncludeEqual).SideIndicator -eq '==' ) {
"The files are equal"
}
Compare-Object outputs nothing if there are no differences and you omit -IncludeEqual, so the above can also be written as:
if ( -not (Compare-Object (Get-Content test1.txt) (Get-Content test2.txt)) ) {
"The files are equal"
}

You can assign a variable to the Compare-Object result. When I did a quick test it seems like nothing is returned if the two objects matched. So you would have to check for $null in the value of the variable.
$a = Compare-Object -ReferenceObject "abc" -DifferenceObject "abc"
if($a -ne $null){continue working here}else{do other action here}
For more info check out:
https://ss64.com/ps/compare-object.html

Related

Powershell - Declaring paths with "$_.pdf" in it

As title says.
I have several if-statements with "Test-Path" in it so it'd be much better if I just declare the variables right away.
$jobs = Get-ChildItem d:\Path\* -recurse -include *.pdf,*.idx |
Select-Object -expand basename |
Sort-Object
$jobs | foreach-object{
if ((test-path d:\Path\$_.idx) -and (test-path d:\path\$_.pdf)){
move-item d:\Path\$_.idx d:\Path
move-item d:\path\$_.pdf d:\Path
}
else {
....
}
}
The file name is varying all the time. That's why I'm using "$_.pdf" for example. This is just a simple example. Add even one more file extension to this and yeah. The code functions like "If pdf and idx basenames are true/equal, move them"
This works completely fine, it's just that putting in the paths for each if statement makes it more confusing.
Any help would be appreciated. Thanks in advance!
Test-Path can take an array of items to be tested. When used so, it will return an array of boolean values. Should that array contain at least one $false, there is at least one missing file. If there isn't, all the files are present.
An example is like so,
# Create a few test files
set-content foo.idx ''
set-content foo.dpf ''
set-content foo.pub ''
# Instead of foo, you'd populate $s with file's basename
# and use a foreach loop
$s ="foo"
# Test if the trio exists. Note variable $s that contains the basename
if( (Test-Path #(".\$s.idx", ".\$s.dpf", ".\$s.pub")) -contains $false){
"nay" # Go here if there was at least one false
}else{
"aye" # go here if all were true
}
# Output
aye
# Change one extension, so trio doesn't exist
if( (Test-Path #(".\$s.idx", ".\$s.dpf", ".\$s.bub")) -contains $false) {
"nay" # Go here if there was at least one false
}else{
"aye" # go here if all were true
}
# Output
nay
I'm dumb.
I just have to put $path\$_.pdf there. thats it

Powershell comparing values / then checking the validity

I have been trying numerous functions in Powershell including Comparison Object, for each function but with no success.
This is what I want to do.
I have two files named as File 1 and File 2. Within File 1, I have a line like this.
In File 2, I have this.
So I want to compare the value of ContractGroups from File 1 to the value of ContractGroups in file 2. If matched, I want to add an outcome to the file.
The difficulty I am having is that I can set up a variable to get the content for matching. But when comparing, I want to only take into account of ContractGroups for a match. So as soon as file 2 is scanned, then I want to see if the value of ContractGroups matches to file 1.
I have tried this.
$file1 = Get-Content "C:\Users\Altunokc\Desktop\Guardian\NotUsed\20200513 Environment parameters\EnvironmentParameters_ICE_EU_PROD.xml"
$file2 = Get-Content "C:\Users\Altunokc\Desktop\inetpub\wwwroot\EU\Guardian\Website\appSettings.config"
$pattern = $file1| %{$_ -MATCH '.Name="ContractGroups" Value'}
$result = "C:\Users\Altunokc\Desktop\Differentdd.txt"
$file1 | foreach { $pattern = $file2 -match $_
if ( $match ) { $match | Out-File -Force $result -Append }
}
and this way
if(Compare-Object -ReferenceObject $(Get-Content $file2 ) -DifferenceObject $(Get-Content $file1 ) | %{$_ -MATCH '.Name="ContractGroups" Value'} -SimpleMatch|
Out-File -FilePath C:\Users\Altunokc\Desktop\Different.txt)
{"match"}
Else {"No "}
No luck.
I think for comparison, I just need to find a way of scanning the line that contains Name="ContractGroups" Value from file 1 and then reading its value (CC) and then scanning file 2 to first see if has a line matches Name="ContractGroups" Value and if yes, and then does the value of it is the same (CC) as file one? If yes, then just write that "Matched" to a blank file.
It would be helpful if you shed light on this. Sorry as I am new on PS.

Find lines in one Object based on strings in other object

Finding lines in one file based on rows in another file.
I have one object $A with some rows like:
0c7d3283-bec2-4db1-9078-ebb79d21afdf
200bc957-26dd-4e8e-aa6e-00dc357c4ac2
218e0d2a-0e8b-4a68-8136-8f5dd749a614
I want to find matches in object $B for those rows and print the lines with the matches to an output file.
I've been trying for a week now (my first week in powershell :) )
I've come to:
$F = $B | ForEach-Object{ $A | Select-String -Pattern $_$ -AllMatches| Select-Object line }
but this doesn't give me any returning results.
Who is willing to help me out?
If you want to match your first Array, with something that should match part of a string in a second array you do something like the code below:
$A = #("0c7d3283-bec2-4db1-9078-ebb79d21afdf", "200bc957-26dd-4e8e-aa6e-00dc357c4ac2", "218e0d2a-0e8b-4a68-8136-8f5dd749a614")
$B = #("Something 0c7d3283-bec2-4db1-9078-ebb79d21afdf", "Something else 200bc957-26dd-4e8e-aa6e-00dc357c4ac2", "Something also e3df3978-beb7-4545-bc48-ff40d8453be1")
foreach ($Line in $A) {
if($B -match $Line) {
$B | Where-Object {$_ -match $Line}
}
}
We first loop through all the lines in the first object, then compare if the line is matched to anything in the second array. If we find a match we go through Array B to find where the Line from A matches.
You could make this code a hell lot prettier, but this the most understandable way I can write it.
Old Answer
You could use the Compare-Object cmdlet to compare the two arrays, then use the -IncludeEqual switch to show where there are matches and then use the -ExcludeDifferent switch to remove the results that do not match.
Then take that Output and put in in a file. A simple test could be something like this:
$A = #("0c7d3283-bec2-4db1-9078-ebb79d21afdf", "200bc957-26dd-4e8e-aa6e-00dc357c4ac2", "218e0d2a-0e8b-4a68-8136-8f5dd749a614")
$B = #("0c7d3283-bec2-4db1-9078-ebb79d21afdf", "200bc957-26dd-4e8e-aa6e-00dc357c4ac2", "e3df3978-beb7-4545-bc48-ff40d8453be1")
(Compare-Object -ReferenceObject $A -DifferenceObject $B -ExcludeDifferent -IncludeEqual).InputObject | Out-File .\output.txt
This should output a file in your Shells current working directory with the two GUIDs that match:
0c7d3283-bec2-4db1-9078-ebb79d21afdf
200bc957-26dd-4e8e-aa6e-00dc357c4ac2
Where the one that didn't match is not included.

delete everything after keyword

I try to merge to files with Compare-Object and I got a file like this:
Number=5
Example=4
Track=1000
Date=07/08/2018 19:51:16
MatCaissierePDAAssoc=
NomImpPDAAssoc=
TpeForceLectPan=0
Number=1
Example=1
Track=0
Date=01/01/1999
You can see it repeats with Number=1. Except with a different value.
I would like to delete everything (everything means not only "= 1") after my keyword "Number" and my keyword itself.
This is what I did so far:
$files = Get-ChildItem "D:\all"
foreach ($file in $files) {
$name = dir $file.FullName | select -ExpandProperty Name
Compare-Object -ReferenceObject (Get-Content D:\original\test.ini) -DifferenceObject (Get-Content $file.FullName) -PassThru |
Out-File ('D:\output\' + $name)
}
And I would like to delete all lines with "Track" and "Date".
My Result should look like this:
Number=5
Example=4
MatCaissierePDAAssoc=
NomImpPDAAssoc=
TpeForceLectPan=0
In fact I need something to delete double keys in my file.
This might help:
# read existing file
$fileContent = Get-Content C:\tmp\so01.txt
# iterate over lines
foreach($line in $fileContent) {
# filter lines beginning with 'Track' or 'Number'
if((-not $line.StartsWith('Track')) -and (-not $line.StartsWith('Number'))) {
# output lines to new file
$line | Add-Content C:\tmp\so02.txt
}
}
Content of C:\tmp\so02.txt:
Example=4
Date=07/08/2018 19:51:16
MatCaissierePDAAssoc=
NomImpPDAAssoc=
TpeForceLectPan=0
Example=1
Date=01/01/1999

Powershell foreach over two arrays

All,
Trying to get this working but have not had any luck with ps.
$a =
"install.res.1028.dll"
"install.res.1031.dll"
"install.res.1033.dll"
"install.res.1036.dll"
"install.res.1040.dll"
"install.res.1041.dll"
"install.res.1042.dll"
"install.res.2052.dll"
$b =
"install.res.1041.dll"
"install.res.1042.dll"
"install.res.2052.dll"
I just wish to have a new array with the values that are found in $a and not found in $b, trying to test it out with write-host but no luck.
I have tried compare-object but I am unable to pull out just the name. I am a totally noob with ps.
Please, any suggestions appreciated.
foreach ($i in $a)
{ foreach-object ($b | where { {$_.name} -ne $i }) { write-host $i}}
Another solution using compare-object as follows:
$c = Compare-Object -ReferenceObject $a -DifferenceObject $b -PassThru
output:
install.res.1028.dll
install.res.1031.dll
install.res.1033.dll
install.res.1036.dll
install.res.1040.dll
CORRECTION:
The above code WILL work for the case where DifferenceObject is guaranteed to be a subset of ReferenceObject. It will FAIL, though, if there are additional objects in DifferenceObject that are not also present in ReferenceObject. The above code returns any objects which are present in EITHER ReferenceObject OR DifferenceObject but NOT in both.
To properly return ONLY objects in ReferenceObject that are not also present in DifferenceObject, the following code is required:
Compare-Object -ReferenceObject $a -DifferenceObject $b |
Where-Object { $_.SideIndicator -eq '<=' } |
ForEach-Object { Write-Output $_.InputObject }
The where-object clause ensures only objects that are present in ReferenceObject are passed down the pipeline.
The foreach-object clause forces the output back to a simple array (ref: Converting Custom Object arrays to String arrays in Powershell - thanks Keith)
$c = $a | Where-Object { $b -notcontains $_ }
This should do the job.
Some Explanation
Where-Object's code block tests each element of the array that's piped into it. The block is supposed to return a boolean value, and if it's true, then the result of the call will contain the item in question.
So for the conditional, we use the -notcontains operator with your second array. $_ refers to the individual item from $a.
This doesn't require an additional or nested loop.