Search code examples
powershellscripting

Remotely replace a string in a text file


I am trying to edit a file on multiple remote machines. I have a command that works locally, but when I try to invoke the command on a remote PC using administrator credentials I am getting an error.

This works locally:

(get-content -Path 'C:\Program Files (x86)\Wycom\WyReceipts\WyReceiptsOverrides.ini') -replace ";End of WyReceipts Settings File",";Local Receipt Archive Directory
LocalPDFArchiveDirectory = C:\Program Files (x86)\WyCom\WyReceipts\LocalReceiptArchive

;End of WyReceipts Settings File" | Out-File -FilePath 'C:\Program Files (x86)\Wycom\WyReceipts\WyReceiptsOverrides.ini'

But when I try this i get errors:

Import-Module ActiveDirectory
$Credentials = Get-Credential
$Credentials.Password | ConvertFrom-SecureString | Set-Content C:\temp\password.txt
$Username = $Credentials.Username
$Password = Get-Content “C:\temp\password.txt” | ConvertTo-SecureString
$Credentials = New-Object System.Management.Automation.PSCredential $Username,$Password
Get-ADComputer -filter 'Name -like "ess-*-Tel*" -or Name -like "ess-*tel*" -and Enabled -eq "True"' | select "Name" | Out-File -FilePath "c:\Temp\WycomPCs.txt"
$computers = get-content -Path "c:\Temp\WycomPCs.txt"

ForEach ($computer in $computers){
Invoke-Command -Credential $Credentials -ScriptBlock {
(get-content -Path 'C:\Program Files (x86)\Wycom\WyReceipts\WyReceiptsOverrides.ini') -replace ";End of WyReceipts Settings File",";Local Receipt Archive Directory
LocalPDFArchiveDirectory = C:\Program Files (x86)\WyCom\WyReceipts\LocalReceiptArchive

;End of WyReceipts Settings File" | Out-File -FilePath 'C:\Program Files (x86)\Wycom\WyReceipts\WyReceiptsOverrides.ini'
}}

Remove-Item -Path "C:\temp\password.txt"

Here is the error message I am receiving:

Invoke-Command : Parameter set cannot be resolved using the specified named parameters.
At c:\mystuff\Scripts\WycomFix.ps1:11 char:1
+ Invoke-Command -Credential $Credentials -ScriptBlock {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Invoke-Command], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands.InvokeCommandCommand

Is there a better way to go about this? Thanks in advance! -Bart (powershell novice, but getting better!)


Solution

    • You're missing a -ComputerName $computer argument in your Invoke-Command calls.

      • Omitting -ComputerName would make the calls local ones, but using -Credential is then not supported - and resulted in the error you saw; in other words: if you use -Credential, you must also use -ComputerName.[1]
    • -ComputerName accepts an array of computers to target in parallel, which is much faster than targeting them in sequence, as in your foreach loop-based attempt.

    Therefore, replace your foreach statement with this:

    Invoke-Command -ComputerName $computers -Credential $Credentials -ScriptBlock {
    
      (Get-Content -Path 'C:\Program Files (x86)\Wycom\WyReceipts\WyReceiptsOverrides.ini') -replace ";End of WyReceipts Settings File",";Local Receipt Archive Directory
    LocalPDFArchiveDirectory = C:\Program Files (x86)\WyCom\WyReceipts\LocalReceiptArchive
    
    ;End of WyReceipts Settings File" | Out-File -FilePath 'C:\Program Files (x86)\Wycom\WyReceipts\WyReceiptsOverrides.ini'
    
    }
    

    [1] Or one of the other parameters that target other computers, either remote ones or VMs. These requirements are enforced via parameter sets.