Weird problem I saw today and I don't understand.
Is there a difference beetween running a script manually in the ISE or Pshell, and as a job?
If I run it manually the code doesn't throw an error - runs smoothly:
Get-ChildItem "\\SERVER\S$\ROOT\DIR" -Recurse | Where {$_.creationtime -lt (Get-Date).AddDays(-35)} | Remove-Item -Force -Include *.conf
But if I run it via Job and let the it export the $error to a txtfile this happens:
Are the rights of my running machine different to the rights of the scheduled job?
Get-ChildItem : Zugriff verweigert
In Zeile:81 Zeichen:1
+ Get-ChildItem "\\SERVER\S$\ROOT\DIR" -Recurse | Where
{$_.creati ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-ChildItem], UnauthorizedA
ccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.Pow
erShell.Commands.GetChildItemCommand
Zugriff verweigert = Access denied
Oh, totally forgot to tell about my windows rights.
Normally the Server I am connecting to is blocked for everybody - except for login with credentials ofc. But somehow my manual powershell script is able to delete and create files?
In "job-mode" it loses it's abilities.
Edit:
Same for the Test-Path commandlet. Manually it shows me true or false. Via job it throws an error.
EDIT - SAME PROBLEM COMPLETELY DIFFERENT Commandlets:
$username = "Administrator"
$password = cat C:\securestring.txt | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
New-PSDrive -Name Z -PSProvider FileSystem -Root \\Server\ROOT -Credential $cred -Persist
test-path 'Z:'
Remove-PSDrive -Name Z -PSProvider FileSystem
This works!
This does not:
$jobname = "Test5"
$JobTrigger = New-JobTrigger -Daily -At "00:18 PM"
$MyOptions = New-ScheduledJobOption -ContinueIfGoingOnBattery -HideInTaskScheduler -RunElevated
Register-ScheduledJob -name "$jobname" -scriptblock {
$username = "Administrator"
$password = cat C:\securestring.txt | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
New-PSDrive -Name Z -PSProvider FileSystem -Root \\Server\ROOT -Credential $cred -Persist
test-path 'Z:'
Remove-PSDrive -Name Z -PSProvider FileSystem
} -trigger $JobTrigger –ScheduledJobOption $MyOptions
You probably have the job running under the SYSTEM account. Use the -Credential parameter to provide your account credentials (whatever account you're logged in with when you successfully run the command interactively).
BTW, Register-ScheduledJob uses the Task Scheduler. You can check the properties of the job in Task Scheduler to see what account it's configured to run as.
Well, it is not exactly an answere to my original question, but I was able to work around my problem by using the invoke-command and test-path from there and giving argument via the -arg.
Invoke-Command -ComputerName $FTPADRESS -ArgumentList $DIRECTORY -ScriptBlock {param ($DIR)
$check = Test-Path -Path "\\SERVER\ROOT\$DIR"
if ($check -ne $true) {New-Item -ItemType directory -Path "\\SERVER\ROOT\$DIR"}
}
Same works with the get-childitem.
Related
I am running PowerShell on CentOS 7.x. I converted working individual commands when running within PowerShell via pwsh to a PowerShell script and then it no longer works. Can someone please shed me some light on what I did wrong?
Here's the working individual commands when running within PowerShell via pwsh.
PS /home/user1/Downloads> $userPw = ConvertTo-SecureString -String "user1password" -AsPlainText -Force
PS /home/user1/Downloads> cd
PS /home/user1> $userCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "user1win", $userPw
PS /home/user1> $s = New-PSSession -computerName 192.168.20.143 -credential $userCredential -Authentication Negotiate
PS /home/user1> Copy-Item -Path /home/user1/Downloads/gssntlmssp-0.7.0-1.el7.x86_64.rpm -Destination "C:\users\user1win\Desktop" -ToSession $s
PS /home/user1> exit
Here's the script when I converted to a PowerShell script so I can pass arguments into it. remote-copy.ps
$remoteHost = $args[0]
$username = $args[1]
$pwp = $args[2]
$source = $args[3]
$destination = $args[4]
Write-Host "Remote Host: '$remoteHost'"
Write-Host "Username: '$username'"
Write-Host "Password: '$pwp'"
Write-Host "Source: '$source'"
Write-Host "Destination: '$destination'"
$pw = ConvertTo-SecureString -String $pwp -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $pw
$s = New-PSSession -computerName $remoteHost -credential $cred -Authentication Negotiate
Copy-Item -Path $source -Destination $destination -ToSession $s
When I run the script, I got the following error.
[user1#rhel7-tm PowerShell]$ pwsh -File ./remote_copy.ps 192.168.20.143 user1win user1password /home/user1/Downloads/vte-0.28.2-10.el7.x86_64.rpm "C:\\users\user1win\Desktop"
Remote Host: '192.168.20.143'
Username: 'user1'
Password: 'user1password'
Source: '/home/user1/Downloads/vte-0.28.2-10.el7.x86_64.rpm'
Destination: 'C:\users\user1win\Desktop'
Copy-Item:
Line |
19 |
Copy-Item -Path "$source" -Destination "$destination" -ToSession $s |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
Starting a command on the remote server failed with the following error message : MI_RESULT_FAILED For more information, see the about_Remote_Troubleshooting Help topic.
Copy-Item: Line |
19 |
Copy-Item -Path "$source" -Destination "$destination" -ToSession $s |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
Failed to copy file /home/user1/Downloads/vte-0.28.2-10.el7.x86_64.rpm to remote target destination.
I would be greatly appreciate if someone can point me to where I did wrong. Thanks!
It's a false alarm. The script does work. The issue is by default the MaxEnvelopeSizekb in winrm/config is only 500kb. I need to set to a bigger value if I want to send a bigger file. To set MaxEnvelopSizekb to 500mb, you need to open PowerShell on Windows as Administrator and run the following command.
PS C:\WINDOWS\system32> Set-WSManInstance -ResourceUri winrm/config -ValueSet #{MaxEnvelopeSizekb = "500000"}
I have a windows service running on one of the Azure VMs.
So whenever a deployment has to be done, we copy the binaries manually. So now, I'm writing a script to do that.
Besically the binaries are in the form of a zip folder in MachineA. That zip folder is copied to MachineB (where windows service is running).After copying, the files are extracted and then zip folder is deleted. Then after the service is started.
To do this I have the below script.
#get session details
$UserName = "$IPAddress\$adminUsername"
$Password = ConvertTo-SecureString $adminPassword -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($UserName, $Password)
$s = New-PSSession -ComputerName $IPAddress -Credential $psCred
#stop the service
Invoke-Command -Session $s -ScriptBlock {Stop-Service -Name "ServiceName" -Force}
#delete existing binaries in destination machine
$tempDestPath = $destinationPath + "\*"
Invoke-Command -Session $s -ScriptBlock {param($tempDestPath)Remove-Item $tempDestPath -Recurse} -ArgumentList $tempDestPath
#copy binaries zip folder in destination machine
Copy-Item -Path $sourcePath -Destination $destinationPath -ToSession $s -Recurse
#extract zipfolder in destination machine
$zipFilePath = $destinationPath + "\" + $fileName
Invoke-Command -Session $s -ScriptBlock {param($zipFilePath,$destinationPath) Expand-Archive $zipFilePath -DestinationPath $destinationPath}-ArgumentList $zipFilePath,$destinationPath
#delete zipfolder in destination machine after extraction
Invoke-Command -Session $s -ScriptBlock {param($zipFilePath)Remove-Item –path $zipFilePath}-ArgumentList $zipFilePath
#start the service
Invoke-Command -Session $s -ScriptBlock {Start-Service -Name "ServiceName"}
This is working fine when I open Windows powershell in MachineA and execute these commands one by one.
But when I put the exact same commands in a ps1 file and execute that file, I'm getting the below error:
At C:\ScriptTest\test.ps1:13 char:95
+ ... -ScriptBlock {Start-Service -Name "ServiceName"}
+ ~~
The string is missing the terminator: ".
At C:\ScriptTest\test.ps1:11 char:42
+ Invoke-Command -Session $s -ScriptBlock {param($zipFilePath)Remov ...
+ ~
Missing closing '}' in statement block or type definition.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString
Where am I missing this terminator. I'm not able to figure out. Any help is highly appreciated.
Turns out a - in one of the commands is wrong.
I have replaced this line
Invoke-Command -Session $s -ScriptBlock {param($zipFilePath)Remove-Item –path $zipFilePath}-ArgumentList $zipFilePath
with this line
Invoke-Command -Session $s -ScriptBlock {param($zipFilePath)Remove-Item -path $zipFilePath}-ArgumentList $zipFilePath
The hyphen in from of the path is slightly different.I was able to figure out from this answer
Problem: Robocopy not launching as another user in Start-Process
The script works fine when running on an account that has the permissions for both file locations but it just doesnt seem to be accepting the -credential param.
Unsure if my formatting is incorrect or if I am doing something wrong.
# Create Password for credential
$passw = convertto-securestring "Password" -asplaintext –force
# Assembles password into a credential
$creds = new-object -typename System.Management.Automation.PSCredential -argumentlist "DOMAIN\Username", $passw
# Select a source / destination path, can contain spaces
$Source = '\\Source\E$\Location'
$Destination = '\\Destination\Location Here'
# formats the arguments to allow the credentials to be wrapped into the command
$RoboArgs = "`"$($Source)`" `"$($Destination)`"" + " /e /Copy:DAT"
# Started Robocopy with arguments and credentials
Start-Process -credential $creds Robocopy.exe -ArgumentList $RoboArgs -Wait
Robocopy will use the standard windows authentication mechanism.
So you probably need to connect to the servers using the appropriate credentials before you issue the robocopy command.
You can use net use to do this.
net use X: '\\Source\E$\Location' /user:MYDOMAIN\USER THEPASSWORD
net use Y: '\\Destination\Location Here' /user:MYDOMAIN\USER THEPASSWORD
net use X: /d
net use Y: /d
and then start your ROBOCOPY
S.Spieker's answer will work, but if you want to use PowerShell built in command and pass the credentials as a pscredential object you could use New-PSDrive to mount the drives:
$passw = convertto-securestring "Password" -asplaintext –force
$creds = new-object -typename System.Management.Automation.PSCredential -argumentlist "DOMAIN\Username", $passw
$SourceFolder = '\\Source\E$\Location'
$DestinationFolder = '\\Destination\Location Here'
New-PSDrive -Name MountedSource -PSProvider FileSystem -Root $SourceFolder -Credential $creds
New-PSDrive -Name MountedDestination -PSProvider FileSystem -Root $DestinationFolder -Credentials $creds
Robocopy.exe \\MountedSource \\MountedDestination /e /Copy:DAT"
Remove-PSDrive -Name MountedSource
Remove-PSDrive -Name MountedDestination
* I might have the Robocopy wrong, it's been years since I used it, but the mounting drives is correct.
I am trying to copy files from a remote server to my base machine using powershell. This throws an 'Access Denied' exception even though the drives get mapped:
New-PSDrive -Name source -PSProvider FileSystem -Root "\\SERVERNAME1\D$\Temp\Folder" ;
New-PSDrive -Name target -PSProvider FileSystem -Root $destinationRemotePath ;
Copy-Item -Path source:\$($file).zip -Destination target: -Verbose -ErrorAction Stop -Force ;
Approach 2
I am mapping the source drive and using PsSession for target drive but I get
Cannot find drive. A drive with the name 'source' does not exist.
+ CategoryInfo : ObjectNotFound: (source:String) [Copy-Item], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
Following is the code being used:
$Username = "UserName";
$Password = ConvertTo-SecureString "Password" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($Username, $Password)
$session = new-pssession -computername 'TargetServerName' -credential $cred
New-PSDrive -Name source -PSProvider FileSystem -Root "\\SERVERNAME1\D$\Temp\Folder" ;
Invoke-Command -Session $session -ScriptBlock { Copy-Item -Path $($args[0]) -Destination $($args[1]) -Verbose -ErrorAction Stop } -ArgumentList source:\$($file).zip,'D:\Folder' ;
There are some issues on that second example:
The PSSession has a different scode, it does not know about your PSDrive.
PSSessions do not support authentication to network location like you might be used to from RDP-Sessions. See CredSSP or ' PSSession double hop'
Approach 1 looks like you have no access to that share you want to use. You can specify credentials via -Credential parameter at New-PSDrive. Can you Get-Childitem on Source: and Target:?
OK so below is my little script that I have come up with that should copy files from my local drive to a remote server using a local server admin user.
$User = "SERVER-NAME\MyUser"
$Password = "Password"
$net = new-object -ComObject WScript.Network
$net.MapNetworkDrive("X:", "\\SERVER-NAME\c$\MyTestFolder\", $false, $User, $Password)
Copy-Item -Path "D:\Path\To\Copy\From" -Destination "X:\" -Recurse -Force -PassThru -Verbose
For some reason I am getting the following error, even though the server is reachable from my machine:
Exception calling "MapNetworkDrive" with "5" argument(s): "The network path was not found."
So it seems that the script is able to copy files only if the folder was actually shared over the network (Folder Properties -> Sharing -> Advanced Sharing). No actual remote access to a file system (which is kinda disappointing).
Here's the simplified version of the script I ended up with:
$User = "SERVER-NAME\AdminUser"
$Password = "Password"
$net = new-object -ComObject WScript.Network
$net.MapNetworkDrive("x:", "\\SERVER-NAME\TestFolder", $false, $User, $Password)
Copy-Item -Path "D:\Path\To\Copy\From" -Destination "x:\" -Recurse -Force -PassThru
$net.RemoveNetworkDrive("x:", 0)
try to create drive with new-psdrive, like this:
$userCRED = "SERVER-NAME\MyUser"
$pass="Password"
$passCRED = ConvertTo-SecureString -String $pass -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $userCRED, $passCRED
$DestinationExport="\\SERVER-NAME\c$\MyTestFolder"
New-PSDrive -Name X -PSProvider filesystem -Root $DestinationExport -Credential $cred
Copy-Item -Path "D:\Path\To\Copy\From" -Destination "X:\" -Recurse -Force -PassThru -Verbose
Remove-PSDrive -Name X