Powershell remotely execute commands - powershell

I am having an issue trying to execute the command remotely. First, the command is trying to copy an executable to the remote system and I think that's where my issue is because you can't access \hostname\C$\Windows\Temp straight, you must connect to C$ first then go to C:\Windows\Temp
That being said, I tried that as well ($Dest = "C$"), and still not working
FYI: The folder might or might not exist in the client
$SetupFolder = "C$\Windows\Temp\Logs"
$Path = "C:\Windows\Temp\Logs\Install.exe"
$Dest = "C$"
# Remote run the install for each system
foreach ($System in $SystemList) {
if (test-Connection -Cn $System -quiet) {
Copy-item $Package -Destination \\$System\$SetupFolder -recurse -Force
if (Test-Path - Path $Path) {
Invoke-Command -ComputerName $System -ScriptBlock {powershell.exe $Path /S} -credential $Credentials
Write-Host -ForegroundColor Green "Installation Successful on $System"
}
} else {
Write-Host -ForegroundColor Red "$System is not online, Install failed"
}
}

You could use Enter-PSSession if you cannot use Invoke-Command, this starts an interactive session with a remote computer, you will need to have permissions on the remote computer first to connect,
More information in the PowerShell documentation,
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/enter-pssession?view=powershell-7.1

Related

jump to next server in the for each loop if pre checks fails

This is start of my script where I do some things to my servers. First I get servers from txt file and check that I have access to net share so can access the package needed and after that move forward using invoke command and script block
foreach ($server in (Get-Content .\myservers.txt)) {
# check access to net share
if (test-path "\\mynetshare\package"){
write-host "I have access to net share on" -ForegroundColor Green
}
else {
write-host "I have not access to net share" -ForegroundColor Red
}
# check the c:\temp
if (test-path "\\$Server\c$\Temp"){
write-host "server has C:\Temp folders." -ForegroundColor Green
}
else {
write-host "server has no C:\Temp. Let's create one."
New-Item -Type Directory "\\$Server\c$\Temp" -Force
}
Copy-Item -path \\mynetshare\package\package.msi -Destination "\\$server\C$\Temp" -Recurse
Invoke-Command -ComputerName $server -ScriptBlock {
my powershell script does magic
}
}
So what do I need to add / change of if I have no access to server (e.g Windows Remote Management (WinRm) problems) so it would not go forward from Invoke-Command -ComputerName $server -ScriptBlock part but instead just jumps the next server in the list?

Installing Program remotely through Remote PowerShell

I am trying to install ActivClient remotely onto some machines, I copy the file to the Public Downloads separately.
I am running into an issue where when I try to run this script, it runs locally on my machine. I need to run that Deploy-Application.PS1 file for this.
I also can't figure out how to Unblock the entire folder, there is a few sub folders and files I would like to unblock.
I can't remote into the computer through RDP because I need ActivClient installed to remote in. Remote PowerShell is the only method I can find to run this.
If I am missing information or need to provide more, please let me know.
$mypath = $MyInvocation.MyCommand.Path
$Path = Split-Path $mypath -Parent
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
$title = 'Computer Name'
$msg = 'Enter the Computer Name you need to reinstall ActivClient on:'
$CName = [Microsoft.VisualBasic.Interaction]::InputBox($msg, $title)
if (Test-Connection -ComputerName $CName -Count 1){
Write-Host "Entering Remote Powershell Session"
$PSSession = New-PSSession -Name $CName
Invoke-Command -Session $PSSession -ScriptBlock{
Get-ChildItem "C:\Users\Public\Downloads\SDC NIPR - ActivClient v7.2.x - 210811_18NOV" | Unblock-File
cd "C:\Users\Public\Downloads\SDC NIPR - ActivClient v7.2.x - 210811_18NOV"
.\Deploy-Application.ps1 Install 'NonInteractive'
pause
}
Use New-PSSession -ComputerName $CName, not New-PSSession -Name $CName.
-Name only gives the session being created a friendly name, it is unrelated to which computer you target. In the absence of a -ComputerName argument, the local machine is (somewhat uselessly) targeted, which is why the script ran on your local machine.
Note that if you're only calling Invoke-Command remotely once per remote computer, you needn't create a session explicitly and can instead use -ComputerName $CName directly with Invoke-Command:
# No need for New-PSSession.
Invoke-Command -ComputerName $CName -ScriptBlock { ... }
Add -Recurse -File to your Get-ChildItem call in order to unblock all files in the target folder recursively (all files in the target folder's subtree).

PowerShell - Invoke Command on Remote Machines/Computers

There's plenty of forums/material regarding the subject line, but cannot seem to get an answer for my problem.
I'm trying to execute a script from the main server (SRV01) that will clean the temp folders on the secondary servers (SRV02, SRV03).
Here is the script:
#Set the machines on the network to run the script on
$VDST = #("SRV02", "SRV03")
#Folder locations to clean out
$TempFolder = #("C:\Windows\Temp\*", "C:\Documents and Settings\*\Local Settings\temp\*")
#This function actually performs the clean up operation
Function executeCleanUp
{
$TempFolder = $args[0]
$machineNames = $args[2]
ForEach($machine in $machineNames){
Get-PSSession -ComputerName $machine | Format-Table -Property ComputerName, InstanceID
Write-Host 'Starting Clean Up...'
#Loop through the sub folders in the registry location
ForEach($folderLocation in $TempFolder)
{
$StrInput = 'Remove-Item -Path ' + $folderLocation + ' -Force -Recurse -ErrorAction SilentlyContinue'
$action = New-ScheduledTaskAction -Execute 'PowerShell.exe' -Argument $StrInput
Register-ScheduledTask -Action $action -TaskName "CleanUp"
Start-ScheduledTask -TaskName "CleanUp"
Unregister-ScheduledTask -TaskName "CleanUp" -Confirm:$false -ErrorAction SilentlyContinue
}
}
#Execute Script on specified machines - provided in array above
Invoke-Command -ComputerName $VDST -ScriptBlock ${function:executeCleanUp} -ArgumentList $TempFolder, $VDST
After running the above, I get the error:
A specified logon session does not exist
So, I came across a forum where it was suggested to do the following:
#Remote Server (VDI)
Enable-WSManCredSSP -Role server
#Expected Output
#This computer is configured to receive credentials from a remote client computer.
#Local Machine
Enable-WSManCredSSP -Role Client -DelegatedCredentials 'SRV01'
#Expected Output
#The machine is configured to allow delegating fresh credentials to the following target(s): wsman/SRV01.
#Local Machine
#Open gpedit.msc
#Browse to Computer Configuration > Administrative Templates > System > Credentials Delegation.
#Double-click "Allow delegating fresh credentials with NTLM-only Server Authentication"
#Enable the setting
#Add the build server to the server list as WSMAN/BuildServerName.
#Example Execution:
#Invoke-Command -ComputerName <REMOTE_COMPUTER_NAME> -Authentication CredSSP -Credential <USERNAME> -ScriptBlock { #code}
I've done all this, but now I get the error:
A computer policy does not allow the delegation of the user
credentials to the target computer
Also, I am assuming the line
WSMAN/BuildServerName
should be written
WSMAN/SRV02
The 2 hop authentication issue came up because you are trying to list remote sessions with in your remote session
Get-PSSession -ComputerName $machine | Format-Table -Property ComputerName, InstanceID
If you just want to clear some files on the remote servers the code below should work with no need for CredSPP.
Setting -ErrorAction SilentlyContinue will make trouble shooting difficult, It's easier to check if the file exists before you try to delete it.
$TempFolder = $args[0]
$ComputerArray = "SRV02","SRV03"
$ScriptBlock =
{
foreach ($Folder in $TempFolders)
{
if (Test-Path -Path $TempFolder)
{
Remove-Item -Path $Folder -force
}
}
}
Invoke-Command -ComputerName $ComputerArray -ScriptBlock $ScriptBlock -ArgumentList $TempFolder
Wrong answer:
Your issue is two hop authentication.
You can't nest remote sessions with default windows settings.
While this would not be considered to be best practice, you can enable CredSSP to bypass the problem.
https://learn.microsoft.com/en-us/windows/win32/secauthn/credential-security-support-provider
https://learn.microsoft.com/en-us/powershell/module/microsoft.wsman.management/enable-wsmancredssp?view=powershell-7
Could you either log on to SVR01 to run the script or run the script against the target machines from your own computer?

PowerShell Script for Importing .reg File to Remote Computer Hanging

I'm using the following script to import a .reg file to remote computers. What I need to happen is the following:
Connect to the remote computer and kill a running process if it's running.
Copy a .reg key file from a Network Share location to the remote computer.
Import the copied .reg key to the remote computer's registry.'
Delete the copied .reg key file from the remote computer.
Start the process that was killed at the beginning.
Now I'm relatively new to PowerShell scripting and the script I have is part cannibalized from scripts I've found searching the internet and my PowerShell Cookbook.
What happens when I run the script is that it'll connect to the remote computer and kill the process, but then the script gets hung up, and doesn't do steps 2-5. It's not throwing out any errors either. What am I missing or doing wrong?
Thanks in advance!
#Variables
$Computers = Get-Content C:\computer.txt
$LocalRegFileName = "regfile.reg"
$HostedRegFile = "\\NETWORK-SHARE\Folder\Folder\regfile.reg"
$ProcessName = "Process"
$FilePath = "C:\Program Files (x86)\Folder\$ProcessName.exe"
foreach ($Computer in $Computers) {
Invoke-Command -ComputerName $Computer {
Get-Process -Name $ProcessName | Stop-Process -Force
}
$NewFile = "\\$Computer\C'$\TEMP\$LocalRegFileName"
New-Item -ErrorAction SilentlyContinue -ItemType directory -Path \\$Computer\C$\TEMP
Copy-Item $HostedRegFile -Destination $NewFile
Invoke-Command -ComputerName $Computer -ScriptBlock {
Start-Process -FilePath "C:\Windows\regedit.exe" -ArgumentList "/s C:\TEMP\$LocalRegFileName"
}
Invoke-Command -ComputerName $Computer -ScriptBlock {
Remove-Item "C:\TEMP\$LocalRegFileName"
}
Invoke-Command -ComputerName $Computer -ScriptBlock {
Start-Process -FilePath "$FilePath\$ProcessName.exe"
}
}

PowerShell Command to Copy File on Remote Machine

I have a requirement to copy file from local machine to remote machine using PowerShell. I can copy the file to remote computer using following command:
copy-item -Path d:\Shared\test.txt -Destination \\server1\Shared
the above command uses network share path to copy the file. I don't want to use network share option as the folder will not be shared on the remote machine. I tried following commands but not working.
copy-item -Path d:\Shared\test.txt -Destination \\server1\c$\Shared
Invoke-Command -ComputerName \\server -ScriptBlock {
copy-item -Path D:\Shared\test.txt -Destination C:\Shared
}
Please let me know how to make it working without using UNC path. I have full permissions on that folder on the remote machine.
Quickest way I found to this, since the account being used is Administrator, is to do the following:
New-PSDrive -Name X -PSProvider FileSystem -Root \\MyRemoteServer\c$\My\Folder\Somewhere\
cd X:\
cp ~\Desktop\MyFile.txt .\
## Important, need to exit out of X:\ for unmouting share
cd c:\
Remove-PSDrive X
Works every time.
You must have a shared folder to be able to copy files from one host to another, either on the remote host if you want to push the file:
Copy-Item -Path D:\folder\test.txt -Destination \\server1\remoteshare\
or on the local host if you want to pull the file:
Invoke-Command -ComputerName server1 -ScriptBlock {
Copy-Item -Path \\localcomputer\localshare\test.txt -Destination C:\Shared\
}
Administrative shares (\\server1\c$) can only be used if your account has admin privileges on that particular computer.
If there is not an accessible share, you'll have to make the file content itself an argument to the script:
Invoke-Command -ComputerName \\server -ScriptBlock {
$args[0] | Set-Content C:\Shared\test.txt
} -ArgumentList (Get-Content D:\Shared\test.txt -Raw)
Powershell 5 (Windows Server 2016)
Also downloadable for earlier versions of Windows. -ToSession can also be used.
$b = New-PSSession B
Copy-Item -FromSession $b C:\Programs\temp\test.txt -Destination C:\Programs\temp\test.txt
Earlier versions of PowerShell
Does not require anything special, these hidden shares exist on all machines.
Copy-Item -Path \\serverb\c$\programs\temp\test.txt -Destination \\servera\c$\programs\temp\test.txt
Invoke-Command -ComputerName compname -Credential $cred -ScriptBlock { Get-Content C:\myfolder\result.txt } >>res.txt
Note the C:\myfolder\result.txt is on the remote computer
Here's a script that worked for me for small files. Run as admin.
#pre 5.0 powershell copy-item to remote computer
Write-Host "Remote copy a file"
$servers = #("server01.dot.com", "server02.dot.com")
foreach($server in $servers) {
$username = 'USERNAME'
$password = 'PASSWORD'
$pw = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object Management.Automation.PSCredential ($username, $pw)
$myfile = [System.IO.File]::ReadAllBytes("C:\Temp\srctest.txt")
$s = New-PSSession -computerName $server -credential $cred
Enter-PSSession $s
Invoke-Command -Session $s -ArgumentList $myfile -Scriptblock {[System.IO.File]::WriteAllBytes("C:\Temp\desttest.txt", $args)}
Write-Host "Completed"
Remove-PSSession $s
}