remove multiple line in file on match

Hi PS,

I want to clean up a file.

im using https://psappdeploytoolkit.com for software deployment and want to cleanup a file before processing it.

i want to remove som sections in the “Deploy-Application.ps1”

Been using this code for some changes but this can only replace a single line at a time.

So how could this be done?

(Get-Content -path C:\Deploy-Application.ps1) -replace 'code1','code2'
        ## Handle Zero-Config MSI Uninstallations
        If ($useDefaultMsi) {
            [hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Uninstall'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
            Execute-MSI @ExecuteDefaultMSISplat
        }
and
   ## Handle Zero-Config MSI Installations
        If ($useDefaultMsi) {
            [hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Install'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) }
            Execute-MSI @ExecuteDefaultMSISplat; If ($defaultMspFiles) { $defaultMspFiles | ForEach-Object { Execute-MSI -Action 'Patch' -Path $_ } }
        }

Did you try to ask your question in the vendor forum https://discourse.psappdeploytoolkit.com/ ? There might be a better way of achieving what you’re after instead of manipulating the code of a Powershell script with another Powershell script. :wink:

No haven’t write in the vendor forum…

Taking this as a learning process manipulating files. So is there a way to remove unwanted lines in a file. If you know the line number?

I could use the “## Handle Zero-Config MSI” as a starting mark but how do I tell ps to remove the 4 lines below.

activating my brain power and came up with this. Is there a better way

$file = “\Deploy-Application.ps1”

function del-line($start, $end, $file) {
$i = 0
$start–
$end–
(Get-Content $file) | where {
($i -lt $start -or $i -gt $end)
$i++
} > $file
(Get-Content $file)
}

function LineNumber ($pattern, $file)
{
$LineNumber = Select-String -Path $file -Pattern $pattern | Select-Object -ExpandProperty LineNumber
return $LineNumber
}

if($(LineNumber -pattern “## Handle Zero-Config MSI Installations” -file $file))
{
$ZeroInstallstart = LineNumber -pattern “## Handle Zero-Config MSI Installations” -file $file
$end = $start + ‘5’
del-line -start $start -end $end -file $file
Write-Host “Installations”
}

if($(LineNumber -pattern “## Handle Zero-Config MSI Uninstallations” -file $file))
{
$start = LineNumber -pattern “## Handle Zero-Config MSI Uninstallations” -file $file
$end = $start + ‘5’
del-line -start $start -end $end -file $file
Write-Host “Uninstallations”
}

If you know the line numbers you want to remove from the file I think it’s easier to output the rest instead of deleting the unwanted lines … like this:

$file = ‘Deploy-Application.ps1’
$Start = 8
$End = 14
$Content = Get-Content -Path $file
Content[0..($Start - 2)]
$Content[$End … $Content.count]

Of course you can pipe the output to whatever further cmdlet you like. :wink:

BTW: please format you code as code like you already did in your first post in this thread. Thanks.

I ended up with this solution - i only knew the comment start pattern so used that as key to match and addd 5 line to that line for removal.

function Zero-ConfigCleanup ($file)
{
	function LineNumber ($pattern, $file)
	{
		$LineNumber = Select-String -Path $file -Pattern $pattern | Select-Object -ExpandProperty LineNumber
		return [int]$LineNumber
	}
	
	function del-line($start, $end, $file)
	{
		$i = 0
		$start--
		$end--
		(Get-Content $file) | where {
			($i -lt $start -or $i -gt $end)
			$i++
		} | set-content $file -Encoding utf8
	}
	
	if ($(LineNumber -pattern "## Handle Zero-Config MSI Installations" -file $file))
	{
		$start = LineNumber -pattern "## Handle Zero-Config MSI Installations" -file $file
		$end = $start + 5
		del-line -start $start -end $end -file $file
	}
	
	if ($(LineNumber -pattern "## Handle Zero-Config MSI Uninstallations" -file $file))
	{
		$start = LineNumber -pattern "## Handle Zero-Config MSI Uninstallations" -file $file
		$end = $start + 5
		del-line -start $start -end $end -file $file
	}
}

[quote quote=185045]If you know the line numbers you want to remove from the file I think it’s easier to output the rest instead of deleting the unwanted lines … like this:

PowerShell
6 lines
<textarea class="ace_text-input" wrap="off" autocorrect="off" autocapitalize="off" spellcheck="false" style="opacity: 0; height: 17.6px; width: 6.59775px; left: 44px; top: 0px;"></textarea>
1
2
3
4
5
6
$file = 'Deploy-Application.ps1'
$Start = 8
$End = 14
$Content = Get-Content -Path $file
$Content[0..$($Start - 2)]
$Content[$End .. $Content.count]
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Of course you can pipe the output to whatever further cmdlet you like. 😉

BTW: please format you code as code like you already did in your first post in this thread. Thanks.[/quote]

Yours looks alot simpler than mine…can you explain what happen in these to lines

$Content[0..$($Start - 2)]
$Content[$End .. $Content.count]

if i wanted the modified text with your way i could pipe it out like this?

$Content | Set-content $file -Encoding utf8

That was the purpose. :wink: You can output any element of an array by using its index.

$array = 1, 2, 3, 4, 5, 6, 7, 8,9,10
$array[5]

Please notice the index of an array starts with 0.
If you like to output a range of consecutive items from the array you can use the range operator like this:
$array[3…8]

Instead of providing the index explicitly you can use variables like this
$Start = 3
$end = 8
$array[$Start … $end]

And because the index is an integer you can calculate with it. :wink:

With Set-Content you would replace the already existing content of a given file. If you have two chunks of lines you want to concatenate you would replace the first chunk with the second one.
I’d recommend creating an new file and using Out-File with the parameter -Append for the second chunk or Add-Content.

$array[0..$($Start - 1)] | Out-File -FilePath 'NewFile.txt' -Encoding utf8
$array[$($End + 1) .. $array.count] | Out-File -FilePath 'NewFile.txt' -Encoding utf8 -Append

Of course there are - as always - a few different ways to achieve a certain goal …

$array[0..$($Start - 1)] + $array[$($End + 1) .. $array.count] | Out-File -FilePath 'NewFile.txt' -Encoding utf8

… or …

$NewContent = $array[0..$($Start - 1)] + $array[$($End + 1) .. $array.count] 
$NewContent | Out-File -FilePath 'NewFile.txt' -Encoding utf8

:wink:

This was interesting. Few things I would maybe add would be the option to choose output format or check what the current file is and use that.

I came up with this function

[pre]

function Remove-DuplicateRowsFromFile
{
[CmdletBinding(SupportsShouldProcess=$true,
PositionalBinding=$false,
ConfirmImpact=‘Medium’)]
Param
(

FilePath

[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
ValueFromRemainingArguments=$false,
Position=0)]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
$FilePath,

Pattern to remove

[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
ValueFromRemainingArguments=$false,
Position=1)]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[string]
$Pattern
)

Begin
{
}
Process
{

$duplicateRows = select-String -Path $file -Pattern $line | select -Skip 1
$rowNumber = 0

$outContent = foreach ($row in (Get-Content $file))
{
$rowNumber++
if ($duplicateRows.linenumber -contains $rowNumber)
{
if ($pscmdlet.ShouldProcess(“Skipping row”, $rowNumber))
{
continue
}
} #if
else
{
$row
} #else
}

} #process
End
{
if ($pscmdlet.ShouldProcess(“Save file”, $file))
{
$outContent | Out-File $FilePath -Encoding utf8
}
} #end
}

[/pre]