Connecting to remote machine from PowerShell - powershell

I am trying to copy files from one domain to a remote machine in another domain. I want to use constant credentials. No matter what I tried, it doesn't work. I can ping to the remote machine only via IP and not by hostname.
$labname='L1681'
$remoteComputer = "10.32.22.157"
$username = "$labname\Administrator"
$password = ConvertTo-SecureString "password" -AsPlainText -Force
$creds = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
$session = New-PSSession -ComputerName $remoteComputer -Credential $creds
$Source = "\\...\folder"
$Destination = "\\$remoteComputer\c$\Users\Administrator\Desktop"
New-Item -ItemType Directory -Path $Destination -Force
Copy-Item -Path $Source -Recurse -Destination $Destination -Force -ToSession $session
I tried to replace the $labname with $remoteComputer. Each time I get a different error:
Enter-PSSession : Connecting to remote server 10.32.22.157 failed with the following error message : The WinRM client cannot process the request. Default authentication may be used with an IP address under the following conditions:
the transport is HTTPS or the destination is in the TrustedHosts list, and explicit credentials are provided. Use winrm.cmd to configure TrustedHosts. Note that computers in the TrustedHosts list might not be authenticated. For more
information on how to set TrustedHosts run the following command: winrm help config. For more information, see the about_Remote_Troubleshooting Help topic.
At line:1 char:1
+ Enter-PSSession -ComputerName $remoteComputer -Credential $creds
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (10.32.22.157:String) [Enter-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : CreateRemoteRunspaceFailed
I hope someone can help me with that, is there a way to know when the copy if finished, once it works? Also, how can I run a .bat file in a remote machine?

You can try this script which establishes a remote connection to a VM and copy a text file from the Local directory to that Remote VM.
#Provide the Remote VM Username and Password
$myPwd="Your VM Password"
$username="VM Username"
$password = ConvertTo-SecureString $myPwd -AsPlainText -Force
$credentials= New-Object System.Management.Automation.PSCredential ($username, $password)
#Create a remote session to that VM
$Session = New-PSSession -ComputerName FQDN/IP -Credential $credentials
#Check the content to the Local File that will be copied to Remote
Get-Content -Path "C:\LocalFolder\File.txt"
#Create a folder named *RemoteFolder* then copy the local file to that Folder
Invoke-Command -Session $Session -ScriptBlock {cd C:\; mkdir RemoteFolder}
Copy-Item –Path "C:\LocalFolder\File.txt" –Destination "C:\RemoteFolder\" –ToSession $Session
#Check the content of the copied file
Invoke-Command -ScriptBlock { Get-Content -Path "C:\RemoteFolder\File.txt" } -Session $Session
The screenshot of the output after running this script:

Related

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?

how to pass a variable in "get-content command " in powershell

I have to get the particular file from one remote desktop to local machine or another server.How to pass a variable in get-content to fetch the file from remote desktop connection?
I store the file path as variable and try to pass it in get-content.
Invoke-Command -Computername $Server -ScriptBlock{get-content -path $file }
Invoke-Command -Computername $Server -ScriptBlock{get-content -path ${file} }
$file="C:\Users\Documents\new DB_connection\\log2.txt"
$Server="servername"
$answer= Invoke-Command -Computername $Server -ScriptBlock{get-content -path $file }
write-output $answer
Cannot bind argument to parameter 'Path' because it is null.
+ CategoryInfo : InvalidData: (:) [Get-Content], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand
You can copy the file over a PSSession instead of using Invoke-Command. To copy from a remote server to a local path or different remote server:
$session = New-PSSession -ComputerName server.domain.tld
Copy-Item -Source $originatingServerFilePath -Destination $localOrUNCFilePath -FromSession $session
If you need to copy a local file to a destination server:
Copy-Item -Source $localFilePath -Destination $destinationServerFilePath -ToSession $session
This has the benefit of not double-hopping, though the server you run the command on will need to have access to any remote file paths. If you need to copy a file from one server to another server, but the destination server doesn't have the filepath exposed as a shared folder (or you don't have access to it) you cannot specify -ToSession and -FromSession at the same time, so you'll have to copy the file locally and use two sessions like so:
$sourceSession = New-PSSession -ComputerName source.domain.tld
$destinationSession = New-PSSession -ComputerName destination.domain.tld
# Copy the remote file(s) from the source session to a local path first
Copy-Item -Source $sourceSessionFilePath -Destination $localTempFilePath -FromSession $sourceSession
# Copy the new local files to the destination session from your local path
Copy-Item -Source $localTempFilePath -Destination $destinationSessionFilePath -ToSession $destinationSession
Try to define the variable inside the ScriptBlock
$Server="servername"
$answer= Invoke-Command -Computername $Server -ScriptBlock{
$file="C:\Users\Documents\new DB_connection\\log2.txt";
get-content -path $file}
write-output $answer

Powershell Remote Copy fails, locally it works

We have logfile on a server A in a different location (no UNC Path access) and we wish to copy the file to server B. This successfully works with Copy-Item -FromSession (run on Server B) as long as the file is closed. So we can successfully copy the previous day's logs but not today's.
$cred = Get-OurUserCredentials
$sess = New-PSSession -ComputerName $ServerA -Credential $cred -Authentication Negotiate
$LogFile = "D:\log\tomcat\access.20180227.log"
Copy-Item -FromSession $sess $LogFile "D:\logs\tomcat\" -Force
However, we can locally copy the active log of today if we run Copy-Item locally on server A. It's only Copy-Item -FromSession on server B which fails with:
Copy-Item : The process cannot access the file 'D:\log\tomcat\access.20180227.log' because it is being used by another process.
At line:11 char:2
As a workaround we could create a local task on server A to create a local copy but why is this necessary?
Why does Copy-Item behave differently when run remotely and can we "fix" it's behaviour so it copies the log remotely as it would locally.
A version of the answer proposed in the OP but avoiding the need for a scheduled task.
$cred = Get-OurUserCredentials
$sess = New-PSSession -ComputerName $ServerA -Credential $cred -Authentication Negotiate
#ScriptBlock to copy file locally
$SB =
{
#Create variables on the remote machine avoid havin gto pass to scriptblock
$LogFile = "D:\log\tomcat\access.20180227.log"
$TempDes = "temporarylocationhere"
Copy-Item -Path $LogFile -Destination $Des
}
#optional scriptblock to clean up
$SB2 =
{
Remove-Item -Path $TempDes -force
}
#Run the copy file scriptblock
Invoke-Command -Session $sess -ScriptBlock $SB
#Copy file
Copy-Item -FromSession $sess $TempDes "D:\logs\tomcat\" -Force #"
#Run clean up scriptblock
Invoke-Command -Session $sess -ScriptBlock $SB2
Have you considered using a PSDrive to map the remote location and then copy the file to or from that drive?
The New-PSDrive cmdlet creates temporary and persistent drives that
are mapped to or associated with a location in a data store, such as a
network drive, a directory on the local computer, or a registry key,
and persistent Windows mapped network drives that are associated with
a file system location on a remote computer.
Example using your code:
# Change the ServerNameToCopyTo below
New-PSDrive -Name "Remote" -PSProvider "FileSystem" -Root "\\ServerNameToCopyTo\log\tomcat\"
$LogFile = "D:\log\tomcat\access.20180227.log"
Copy-Item $LogFile "Remote:\" -Force

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
}

how to copy a file from local pc to remote using remote credentials powershell

i am trying to copy a file from my local pc and paste it to the remote computer but i am getting logon error. if i use the invoke command with -credential parameter than it works, but first i would like to copy the files from local to the remote server. here is my code
$pwd = convertto-securestring "password1234" -asplaintext -force
$cred=new-object -typename System.Management.Automation.PSCredential -argumentlist
".\Administrator",$pwd
$localpath = "C:\_Projects\test.ps1"
$destination = "\\my ip\c$\_Projects\Deployments\"
copy-item -path $localpath -destination $destination -recurse -Force -Credential $cred