1

I have a powershell script that simply updates a file on a couple different webservers. Each of these web servers have different local credentials that I need to provide in order to access the file in question. How can I update my script to allow for this?

#message
$statusMessage = "hello world"

#servers to update
$servers = @("1.1.1.1","2.2.2.2")

#update files
foreach ($server in $servers) {
  Set-Content -Path "\\$server\c$\blah\foo.htm" -Value $statusMessage
}

Again, each server has it's own local Admin credentials that I need to use.

Brian David Berman
  • 7,514
  • 26
  • 77
  • 144
  • Why local credentials? Why not a domain account that has access to all of the servers? – Bill_Stewart Dec 28 '17 at 17:33
  • @Bill_Stewart current/unfortunate limitation, the best I can do is have matching local credentials – Brian David Berman Dec 28 '17 at 17:35
  • 1
    Unfortunately `-Credential` doesn't work with `Set-Content`. (Run `help Set-Content -Full` - comment there notes "This parameter is not supported by any providers installed with Windows PowerShell.") – Bill_Stewart Dec 28 '17 at 19:09

2 Answers2

2

One way to do this, if you really are forced to use local accounts (avoiding this problem is one of the purposes of having a domain), is to authenticate on the server using net use, copy the file, then disconnect. Example:

$userName = Read-Host "Enter user name for computer1"
net use \\computer1\ipc$ /user:$userName *
Set-Content \\computer1\c$\whatever\file.htm "Content here"
net use \\computer1\ipc$ /delete

Of course you can generalize the computer name within the loop. In this example, you will have to manually enter the user name and password for each computer.

Bill_Stewart
  • 22,916
  • 4
  • 51
  • 62
1

Since the -Credential parameter of Set-Content doesn't seem to actually work (as Bill_Stewart pointed out) you basically have 3 options AFAICS:

  • Use net use to authenticate a session as Bill suggested in his answer, then write to the UNC path.
  • Map a network drive, either via net use or the PoSh way:

    $username = 'Administrator'
    $password = ConvertTo-SecureString 'password' -AsPlainText -Force
    $cred = New-Object Management.Automation.PSCredential ($username, $password)
    
    $drive = New-PSDrive -Name X -PSProvider FileSystem -Root "\\$server\c$\blah" -Persist -Credential $cred
    Set-Content -Path 'X:\foo.htm' -Value $statusMessage
    $drive | Remove-PSDrive
    
  • Run Set-Content on the remote server and have it write to a local path.

    $username = 'Administrator'
    $password = ConvertTo-SecureString 'password' -AsPlainText -Force
    $cred = New-Object Management.Automation.PSCredential ($username, $password)
    
    Invoke-Command -Computer $server -ScriptBlock {
        Param($msg)
        Set-Content -Path C:\blah\foo.html -Value $msg
    } -ArgumentList $statusMessage -Credential $cred
    

For both PowerShell approaches you'll have to prepare a PSCredential object as shown above, or just pass the username (in which case you'll be prompted for the password).

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328