Let's suppose I have a CSV file named "PCs.csv" with three 'columns' ("name","user","pw").
Now, let's also suppose that I want to run a very simple command on each PC, using the credentials associated with it.
Initially, since Server and Workstation are both using PS 5.0 (and PSRemoting is Enabled), I was testing with Invoke-Command
and result output was exactly what I wanted (which is exactly the same as if I'd been on the machine running the command). The problem with this, however...is that I was on the machine. As the user to whom the credentials powershell was using to run the command belong. And the results were not evident in the slightest.
Then...I figured I'd use PSExec. That returns an error stating:
psexec.exe : The system cannot find the file specified.
At line:7 char:5
+ & C:\PSTools\PSExec.exe \\$pc.name /accepteula -u $un -p $pc.pw "n ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (The system cann...file specified.:Strin
g) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Error opening {name=PC01; user=user01; pw=pass01}.name:
So, below are the two scripts I used...I just need one of them to work. In fact, that's a lie...I don't even need one of them to work...if there's something else that will work better, I'm equal opportunity!
Invoke-Command:
$PCs = Import-Csv "C:\PCs.csv"
ForEach ($pc in $PCs) {
$un = "DOM\" + $pc.user
$pw = ConvertTo-SecureString $pc.pw -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ($un,$pw)
Invoke-Command -ComputerName $pc.name -Credential $creds -ScriptBlock {
cmd.exe /c "net use * /delete /yes"
}
}
And PSExec:
$PCs = Import-Csv "C:\PCs.csv"
ForEach ($pc in $PCs) {
$un = "DOM\" + $pc.user
& C:\PSTools\PSExec.exe \\$pc.name /accepteula /u $un /p $pc.pw "net use * /delete /yes"
}
I'm sure there's something really stupid I'm missing, so I do apologize for that ahead of time. But, on the bright side - if that is the case, at least we can all have a hearty laugh :)
If there's no need to disconnect a drive mapping in use by a logged on session, you don't need psexec, as you don't need to run the command in a user session. Impersonating as the user, and loading the profile is sufficient, because drive mappings get stored by net use
(in case a drive letter was provided, and the /persistence flag set) in the user specific part of the registry, HKCU (Get-Childitem -path HKCU:\network
shows the persistent drive mappings, net use
shows the active drive mappings). To verify this, first I logged on to a session using RDP, and made a drive mapping with the persistent flag. Then I used your script to remove this drive mapping:
$PCs = Import-Csv "C:\PCs.csv"
ForEach ($pc in $PCs) {
$un = "SSS\" + $pc.user
"user: $un, password: $($pc.pw)"
$pw = ConvertTo-SecureString $pc.pw -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ($un,$pw)
Invoke-Command -ComputerName $pc.name -Credential $creds -ScriptBlock {
whoami /user
Get-Childitem -path HKCU:\network
cmd.exe /c "net use * /delete /yes"
Get-Childitem -path HKCU:\network
}
}
The next time I logged on using RDP, the drive mapping was not created anymore.