How to read a specific item of INI file using PowerShell? - powershell

I want to read a specific item of my INI file, I have 5 Items in the section of my INI file, and I want to read 4 items, except items number 3.
I already tried to read all the items, but I can not find a way how to specify the item that I want to read and the format of the file that I read is like this:
Name Value
AA 12
BB 13
CC 14
DD 15
EE 16
I used this command to execute it.
File1.ps1 Read-File -FilePath C:\Users\Data.ini -a_section Code -store C:\Users\
function Read-File {
Param(
[Parameter(Mandatory=$true)]$FilePath,
[Parameter(Mandatory=$true)]$a_section,
[Parameter(Mandatory=$true)]$store
)
$input_file = $FilePath
$ini_file = #{}
Get-Content $input_file | ForEach-Object {
$_.Trim()
} | Where-Object {
$_ -notmatch '^(;|$)'
} | ForEach-Object {
if ($_ -match '^\[.*\]$') {
$section = $_ -replace '\[|\]'
$ini_file[$section] = #{}
} else {
$key, $value = $_ -split '\s*=\s*', 2
$ini_file[$section][$key] = $value
}
}
$Path_Store = $store
$Get_Reg = $ini_file.($a_section)
$Output = $Get_Reg | Out-File $Path_Store\Out_Test
}
$cmd, $params = $args
& $cmd #params
My expectation result, I have an output file like this
AA=12
BB=13
DD=15
EE=16
My INI File look like this:
[Name]
1=Joe
2=Grace
[Code]
AA=12
BB=13
CC=14
DD=15
EE=16

Try this:
function Get-IniSection {
Param(
[Parameter(Mandatory=$true)]$Path,
[Parameter(Mandatory=$true)]$SectionName
)
$ini_file = #{}
Get-Content $Path | ForEach-Object {
$_.Trim()
} | Where-Object {
$_ -notmatch '^(;|$)'
} | ForEach-Object {
if ($_ -match '^\[.*\]$') {
$section = $_ -replace '\[|\]'
$ini_file += #{ $section = #{} }
} else {
$key, $value = $_ -split '\s*=\s*', 2
$ini_file[$section] += #{ $key = $value }
}
}
return $ini_file[$SectionName]
}
$section = Get-IniSection -Path "C:\temp\test.ini" -SectionName "code"
$section.GetEnumerator() | Where-Object { $_.Name -ne "EE" }
$section.GetEnumerator() | ForEach-Object { "$($_.Name)=$($_.Value)" }
$section.GetEnumerator() |
Where-Object { $_.Name -in #("A1","AE","AP","AS","E1","E2","JP","M1","M2","N1","N2","P1","P2","P3","P4","PR","RU","S1","S2","W1","W2","W3","W4","ZH") } |
Select-Object -ExpandProperty "Value"
$section.GetEnumerator() |
Where-Object { $_.Name -in #("A1","AE","AP","AS","E1","E2","JP","M1","M2","N1","N2","P1","P2","P3","P4","PR","RU","S1","S2","W1","W2","W3","W4","ZH") } |
Foreach-Object { ($_.Value -split ",")[0] }

Related

How do I use Function in PowerShell to execute from Command Line?

I want to execute my script with command line. I use function inside my script.
I used this script:
Function Get-IniFile
{
Param(
[parameter(mandatory=$true)][string]$FilePath
)
$input_file = $FilePath
$ini_file = #{}
Get-Content $input_file | ForEach-Object {
$_.Trim()
} | Where-Object {
$_ -notmatch '^(;|$)'
} | ForEach-Object {
if ($_ -match '^\[.*\]$') {
$section = $_ -replace '\[|\]'
$ini_file[$section] = #{}
} else {
$key, $value = $_ -split '\s*=\s*', 2
$ini_file[$section][$key] = $value
}
}
$Get = $ini_file.Class.Amount
$Get
}
I execute this script from command line with this command:
PowerShell.ps1 Get-IniFile -FilePath
I dont get any result when I execute this code, but If I remove "Function Get-IniFile" I got the value of Amount.
This is my INI file
[Class]
Amount = 1000
Feature = 20
[Item]
Set = 100
Return = 5
You have to call your function inside your script. The script code is like your main function in C# or Java.
PowerShell.ps1 content :
# Global script parameters.
Param(
[parameter(mandatory=$true)][string]$FilePath
)
# Definition of the function
Function Get-IniFile
{
Param(
[parameter(mandatory=$true)][string]$Path
)
$input_file = $Path
$ini_file = #{}
Get-Content $input_file | ForEach-Object {
$_.Trim()
} | Where-Object {
$_ -notmatch '^(;|$)'
} | ForEach-Object {
if ($_ -match '^\[.*\]$') {
$section = $_ -replace '\[|\]'
$ini_file[$section] = #{}
} else {
$key, $value = $_ -split '\s*=\s*', 2
$ini_file[$section][$key] = $value
}
}
$Get = $ini_file.Class.Amount
$Get
}
# Calling the function with the global parameter $FilePath
Get-IniFile $FilePath

How to edit INI file value in Powershell?

I have an INI file:
[Name]
Female = 10
Male = 30
[Class]
Kids = 2
Adult = 10
I want to change the value of each section. Give me idea please.
I tried this code:
function Set-OrAddIniValue
{
Param(
[string]$FilePath,
[hashtable]$keyValueList
)
$content = Get-Content $FilePath
$keyValueList.GetEnumerator() | ForEach-Object {
if ($content -match "^$($_.Key)=")
{
$content= $content -replace "^$($_.Key)=(.*)", "$($_.Key)=$($_.Value)"
}
else
{
$content += "$($_.Key)=$($_.Value)"
}
}
$content | Set-Content $FilePath
}
this is the code
You would do so:
$ini = Get-IniContent "<pathToYourIniFile>"
$ini["<yourSection>"]["<yourKey>"] = "<yourValue>"
$ini | out-inifile -FilePath "<pathToYourIniFile>"
If you updated your code to the following, it will be more successful:
function Set-OrAddIniValue
{
Param(
[string]$FilePath,
[hashtable]$keyValueList
)
$content = Get-Content $FilePath
$keyValueList.GetEnumerator() | ForEach-Object {
if ($content -match "$($_.Key)\s*=")
{
$content= $content -replace "$($_.Key)\s*=(.*)", "$($_.Key)=$($_.Value)"
}
else
{
$content += "$($_.Key)=$($_.Value)"
}
}
$content | Set-Content $FilePath
}
One problem will be if you add extra key/value pairs, they will all be added to the last section. In other words, the code is not section-aware.

Removing extra blank space from PowerShell output

I have a PowerShell program to replace some strings with another from an input file but the output file has an extra space/line when compared to input file.
$InputACKFile = 'C:\Testing_Newline\Aj*.dat'
Write-Host "Found " ($InputACKFile | Measure-Object).Count " files to process"
$InputACKFile = Get-ChildItem $InputACKFile
foreach ($xfile in $InputACKFile) {
Write-Host "Processing file: $xFile`r"
#((Get-Content $xfile).Replace("~", "`n")) | Out-File $xfile.FullName
[System.IO.File]::ReadAllText($xfile).Replace("~","`n") |
Set-Content $xfile
$flag = 0
(Get-Content $xfile | ForEach {
if ($_ -match "^PQ\*") {
$_ -replace "test1", "test2"
} elseif ($_ -match "^TA\*") {
$_ -replace "test1", "test2"
} elseif ($_ -match "^ABC\*RS\*") {
$_ = '';
$flag = 1
} elseif ($_ -match "^(DE\*)([0-9]+)(\*[0-9]+)$" -and $flag -eq 1) {
$_ -replace ($matches[2]), ([int]::Parse($matches[2])-1);
$flag = 0
} else{
$_
}
}) | Out-File $xfile.FullName -Encoding Ascii
((Get-Content $xfile) -join("~")) | Set-Content $xfile.FullName
}

Powershell - Pattern Matching

I have a requirement wherein the log file has some IP address and it needs to be replaced with hostname referring the database. I am getting output with matches for hostname found in database. I am unable to print the IP address for which hostname not found as it is.Can anyone assist in getting the full output.
IP_Address.txt
dhhdhja sasa 10.1.154.6
sasas swssss 10.1.154.10
assas 10.1.154.14
10.1.154.34
10.1.154.38
Hostname.txt
10.1.154.6=>Host1
10.1.154.10=>Host2
10.1.154.14=>Host3
Current Output
dhhdhja sasa 10.1.154.6=>Host1
sasas swssss 10.1.154.10=>Host2
assas 10.1.154.14=>Host3
Expected Output
dhhdhja sasa 10.1.154.6=>Host1
sasas swssss 10.1.154.10=>Host2
assas 10.1.154.14=>Host3
10.1.154.34
10.1.154.38
Code
$log = "C:\Users\IP_Address.txt"
$DB=#()
$DB = Get-Content C:\Users\Hostname.txt
Get-Content $log |
Where-Object {$_ -match '(?<IP>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'} |
ForEach-Object {
# Try to resolve the IP
Try
{
$IP = $Matches.IP
foreach($DBE in $DB)
{
if($IP -match $DBE.split("=>")[0])
{
$hostname = $DBE
if ($hostname -ne "")
{
Get-Content $log |
Where-Object {$_ -match $IP} |
ForEach-Object {
$_ -replace $IP, $hostname
}
}
}
}
}
catch
{
#$_ -replace $IP, $IP
}
}
Finally I was able to solve it..
Code:
$log = "C:\Users\IP_Address.txt"
$DB=#()
$DB = Get-Content "C:\Users\Hostname.txt"
$file = Get-Content "C:\Users\Hostname.txt"
Get-Content $log |
Where-Object {$_ -match '(?<IP>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'} |
ForEach-Object {
$IP = $Matches.IP
$containsWord = $file | %{$_ -match $IP}
If($containsWord -contains $true)
{
# Try to resolve the IP
$IP = $Matches.IP
foreach($DBE in $DB)
{
if($IP -match$DBE.split("=>")[0])
{
$hostname = $DBE
if ($hostname -ne "")
{
Get-Content $log |
Where-Object {$_ -match $IP} |
ForEach-Object {
$_ -replace $IP, $hostname
}
}
}
}
}
Else{$_}
}
Try this:
$log = "C:\Users\IP_Address.txt"
$DB=#()
$DB = Get-Content C:\Users\Hostname.txt
## Loop through each line in IP_Address.txt to do the replacement, as needed
Get-Content $log | ForEach-Object {
## Perform work if we run into a line with an IP
if ($_ -match '(?<IP>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})') {
$DBE = $DB | ? { $_ -like "$($_)*" }
## Make sure the entry we get back is a valid IP
if ($DBE -match '(?<IP>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})') {
$_.Replace($_, $DBE) ## Replace just the IP with the IP/hostname from hostname.txt
} else {
$_ ## Else just emit the line as-is which still contains the original IP
}
} else {
$_
}
}

Add Content in Powershell

I need to search through multiple files and underneath specific lines i need to insert lines referenced previously in each respective file. So far i cannot get my script to work at all.
This is what i have so far :
$TextLocation = "M:\test"
$files = get-childitem -filter *.gto -path $TextLocation
Foreach ($file in $files) {
$pagetitle = "DS_PGSEQ-DC:"
$a = Get-Content $file.FullName | Select-String "AssignedToUserID-TZ"
$b = Get-Content $file.FullName | Select-String "EFormID-TZ"
Foreach ($line in $file)
{
if([String]$line -eq "DS_PGSEQ-DC:0001")
{
}
elseif([String]$line -eq $pagetitle)
{
Add-Content $file.FullName ($a -and $b)
}
}
}
There are two common ways for inserting text into a text file:
Process the input file(s) line-by-line, write the output to a temporary file and replace the input file(s) with them temp file afterwards.
for ($file in $files) {
$filename = $file.FullName
Get-Content $filename | % {
if ( $_ -match 'seach pattern' ) {
$_
"new line"
}
} | Out-File $tempfile
MoveItem $tempfile $filename -Force
}
Read the entire content of the file(s), insert the text by using a regular expression replacement, and write the modified content back to the file(s).
for ($file in $files) {
$text = [System.IO.File]::ReadAllText($file.FullName)
$text -replace '.*search pattern.*', "`$0`nnew line" |
Out-File $file.FullName
}
$TextLocation = "M:\test"
$Outputlocation = "M:\test\output"
$files = get-childitem -filter *.gto -path $TextLocation
Foreach ($file in $files) {
$pattern = "\d\d\d[2-9]"
$found=$false
$contains=$false
$lines = Get-Content($file.FullName) |
Foreach-object {
if ($_ -match "AssignedToUserID-TZ") {
$a = $_
}
if ($_ -match "EFormID-TZ") {
$b = $_
}
if ($_ -match "DS_PGSEQ-DC:$pattern") {
if($found -eq $false) {
$found=$true
}
} else {
$found=$false
}
if ($found -eq $true) {
$contains=$true
#Add Lines after the selected pattern
$_
$a
$b
}
if ($found -ne $true) {
$_
}
} | Set-Content($Outputlocation + "\" + $file.Name)
}