how to pass a variable in "get-content command " in powershell - 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

Related

Replicating file to remote server, Issue while joining path of local and remote server copying files in powershell

enter code hereI am facing issue while replicating files to remote server, joining the path failing somehow.
Below is code:
Invoke-Command -ComputerName $RemoteServer -ScriptBlock {param($DestinationDir,$LocalCertResultObj,$RemoteCertResultObj,$SourceDir) Compare-Object $LocalCertResultObj $RemoteCertResultObj -Property Name, Length, FullName | Where-Object {$_.SideIndicator -eq "<="} | ForEach-Object {
{$DestinationDir = Join-Path $DestinationDir $_.FullName.Substring($SourceDir.length)}
Write-Output $DestinationDir
Write-Output $SourceDir
Copy-Item -Path "$SourceDir\$($_.name)" -Destination "$DestinationDir" -Recurse -Force
} } -ArgumentList $DestinationDir,$LocalCertResultObj,$RemoteCertResultObj,$SourceDir -Credential $RemoteMachine_cred
Getting error like below:
$DestinationDir = Join-Path $DestinationDir $_.FullName.Substring($SourceDir.length)
C:\TestFolderR
C:\TestFolder
Cannot find path 'C:\TestFolder\file1.txt' because it does not exist.
+ CategoryInfo : ObjectNotFound: (C:\TestFolder\file1.txt:String) [Copy-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
Joining the path looks to be working fine. Copy-Item's error is pretty clear that it can't find C:\TestFolder\file1.txt. Since you're presumably trying to copy this file to the remote server, your ScriptBlock used with Invoke-Command is going to run that entire ScriptBlock on the remote system. It's not going to be able to copy that file over the PowerShell session because it's not aware of your local filesystem - at least, not by using Invoke-Command.
You can establish a New-PSSession to the remote system, and use this with Copy-Item directly from your local session to the remote filesystem:
$Session = New-PSSession -ComputerName server.domain.tld -Credential $RemoteMachine_Cred
Copy-Item -ToSession $Session -Path $localPath-Destination $remotePath
You can even copy an item from the remote filesystem back to your local system, too. Using the same $Session we established above:
Copy-Item -FromSession $Session -Path $remotePath -Destination $localPath

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

Copy files from UNC path to C:\ and Program files (x86) folder within a remotly generated New-PSSession

I am writing a script, that creates a new VM, connects to it via New-PSSession and runs serveral Commands to alter a few settings and copy folders from a UNC path to the local C: and C:\Program files (x86).
Everything works fine expect the copy part - I get an error saying
permission denied.
I run the script itself as domain admin and the credentials I pass also has domain admin rights.
For example:
$source = '\\server\share'
$cred = Get-Credential
$pss = New-PSSession -ComputerName "$computername" -Credential $cred
Invoke-Command -Session $pss -ScriptBlock {
Copy-Item "$source\FOLDER" -Destination 'C:\FOLDER' -Recurse -Force -
Credential
$cred
Even if I pass the cedentials it fails. A quick search results in "use robocopy", but in my opinion it must be possible to copy files from a UNC path to a local directory with PowerShell even if that directory is basically protected by Microsoft.
I think you need to pass the variable to the remote session:
invoke-Command -Session $pss -Args $source -ScriptBlock{Copy-Item "$args[0]\FOLDER" ...}
otherwise $source is considered a variable in the remote session and since it doesn't exist there ps will try to copy from \Folder
You can try to use -ToSession parametr without entering to PSSession.
$ses = New-PSSession -ComputerName WorkStation
Copy-Item -ToSession $ses -Destination C:\users\TempUser\Documents\ -Path '\\10.0.0.1\share\' -Recurse
My solution for Copy-Item is:
-Destination $($(dir "env:programfiles(x86)").value + "\Avest\AvPCM_nces\")

Powershell Remote file copy is not working

I am trying to copy files remotely on several IIS servers from one source server.
sourcepath is a UNC path like \\server\c$\path\ and destinationpath is a local folder c:\data\destination\
The strange thing is when I run this on the local server this will work perfectly.
$cmd = $sqlConnection.CreateCommand()
$cmd.CommandText ="SELECT * from infrastructure"
$Serverinfo = $cmd.ExecuteReader()
try
{
while ($Serverinfo.Read())
{
$servername = $Serverinfo.GetValue(1)
$location = $Serverinfo.GetValue(2)
#Invoke-Command -ComputerName $servername { new-item -Path $Using:destinationpath -name $Using:versionnumber -Itemtype directory }
Invoke-Command -ComputerName $servername { Copy-Item -Path $Using:sourcepath -destination $Using:destinationpath }
#Invoke-Command -ComputerName $servername {Import-Module WebAdministration ; New-WebApplication -force -Site "Default Web Site" -Name $Using:versionnumber -PhysicalPath $Using:destinationpath$Using:versionnumber }
}
}
What you have posted is incomplete without a catch block and source and destination path defined as others said.
But what I can see here as a possible cause even if you mention all above three constrains.
You will face issues with credential delegation . You are remoting to one server using PSRP and copying one file to that machine and you are taking your source file from a UNC path which requires some authentication.
I could give you two better alternatives, of course 1st once could be the proper solution.
If you are in PS 5.o or later, you can use -ToSession parameter of Copy-Item cmdlet.
$Session = New-PSSession -ComputerName $ServerName
Copy-Item -SourcePath \\\Server\c$\path -Destination c:\data\Destination-ToSession $Session
For more info Get-Help Copy-Item
Edit:
The second one:
Copy-Item -Path <Sourcepath> -DestinationPath \\destinataionserver\c$\folder
from source to the destination by accessing the shared folder of the destination system.

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
}