I have a powershell forum for level 1.
Now it has been asked to add a button that calls an script for solving automatic outlook issues.
The script works when i call it direct on the computer itself (via .\outlook.ps1)
When i add it to the button it does not work.
The button itself works and is visible.
example code:
$button_Outlookrest_Click={
Get-ComputerTXTBOX
Add-logs -text "$ComputerName - Create new Outlook profile"
function button{
Copy-Item -Path "D:\path\Repair_outlook_Profile.ps1" -Destination "\\$ComputerName\C$\local" -Recurse
Invoke-Command -ComputerName $ComputerName -ScriptBlock {C:\local\Repair_outlook_Profile.ps1}
}
}
I have tested the code individual, and the following is working:
Copy-Item -Path "D:\path\Repair_outlook_Profile.ps1" -Destination "\\replaced-with-targetcomputer\C$\local" -Recurse
When i whant to call the script, i use the following:
Invoke-Command -ComputerName $ComputerName -ScriptBlock {C:\local\Repair_outlook_Profile.ps1}
However, above text provides me below error:
PS C:\Users\admin> Invoke-Command -ComputerName targetcomputer -ScriptBlock {C:\local\Repair_outlook_Profile.ps1}
[targetcomputer] Connecting to remote server targetcomputer failed with the following error message : WinRM cannot
complete the operation. Verify that the specified computer name is valid, that the computer is accessible over the
network, and that a firewall exception for the WinRM service is enabled and allows access from this computer. By
default, the WinRM firewall exception for public profiles limits access to remote computers within the same local
subnet. For more information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (clienttarget:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : WinRMOperationTimeout,PSSessionStateBroken
i want to avoid them using powershell, as its not the idea of this button.
in the script itself, it does not copy the file to the target computer, it does not run the script using the invoke command.
Is this blocked by company firewall?
Do i have something wrong in my code?
An example button that works without any problem is:
$button_DriverQuery_Click={
$button_DriverQuery.Enabled = $False
Get-ComputerTxtBox
$DriverQuery_command="cmd.exe"
$DriverQuery_arguments = "/k driverquery /s $ComputerName"
Start-Process $DriverQuery_command $DriverQuery_arguments
$button_DriverQuery.Enabled = $true
}
Only this aditional button does not work. And i cannot figure it out at the moment.
What am i doing wrong here?
thank you.
Related
I notice an error " Connecting to remote server usa-chicago failed with the following error message : Access is denied. For more information, see the
about_Remote_Troubleshooting Help topic
CategoryInfo : OpenError: (usa-chicago:String) [], PSRemotingTransportException
FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken
". Below is the snippet used. Any suggestions?
All the machines are inside a workgroup.
$computers = gc "C:\servers.txt"
$source = "\\usa-chicago\c$\temp\one.jar"
$destination = "c$\july1\folder1\"
foreach ($computer in $computers) {
Invoke-Command -Computername $computer -ScriptBlock { & Copy-Item $using:source -Destination \\$using:computer\$using:destination -Force }
}
Does your user account have access both to the computer and also the share you try to copy something to? It could be that you hit the dreaded 'second hop' problem with PowerShell Remoting: https://learn.microsoft.com/en-us/powershell/scripting/learn/remoting/ps-remoting-second-hop?view=powershell-7
If this is the problem, there are some workarounds for that. What i like to do is:
In the Invoke Command, create a Scheduled Task with the commands you'd like to execute and pass the credentials into it, execute it, and delete it after.
Because VSCode is not able to run a powershell console and debug it as a different user i am trying to get arround it with invoked credentials like this:
Start-Service -Name "WinRM"
$cred = Get-Credential -Credential domain\myuser
Invoke-command -Credential $cred -Computer "localhost" -scriptblock {
Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1"
Set-Location 'XXX:' # my sccm site code
Import-CMComputerInformation -CollectionName "All Systems" -ComputerName "TestComputer" -MacAddress "00:00:00:00:00:69"
}
If i start it in the debugger of VSCode (F5) it starts but cant connect then to the SCCM Server infrastructure. Could someone help me to solve this issue?
Error:
Cannot find drive. A drive with the name 'XXX' does not exist.
+ CategoryInfo : ObjectNotFound: (XXX:String) [Set-Location], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
+ PSComputerName : localhost
This command cannot be run from the current drive. To run this command you must first connect to a Configuration Manager drive.
+ CategoryInfo : DeviceError: (Microsoft.Confi...ormationCommand:ImportComputerInformationCommand) [Import-CMComputerInformation], InvalidOperationException
+ FullyQualifiedErrorId : CommandCannotExecuteFromCurrentDrive,Microsoft.ConfigurationManagement.Cmdlets.Oob.Commands.ImportComputerInformationCommand
+ PSComputerName : localhost
If i logoff from my machine and login with my admin credentials and execute everything in the invoke-command scriptblock it works.
As i am not allowed to work like this by our company policy's is there maybe a alternative way or something i can do to use the visual studio code debugger?
Have you logged onto the SCCM site server interactively with the credentials you are using and opened the console at least once? I believe this initial first opening is required before the drive is accessible remotely...
I'd like to install software on some of my domain computers silently. Since these software packages don't come in the form of an MSI, I thought I'll try to do it using Powershell.
In a first step, I set up Powershell remoting. The following command works:
PS $ Test-WSMan -ComputerName rmtComputer
wsmid : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd
ProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor : Microsoft Corporation
ProductVersion : OS: 0.0.0 SP: 0.0 Stack: 3.0
The software packages to be installed are on network shares. Unfortunately, it doesn't seem possible to start these install files directly. As Kevin Marquette explains in his article on Powershell, this is due to some double hop credential problem. The solution is to first copy the setup file from the share to a local folder, then start the setup.
In the same article, he shows 2 ways of doing that. The first way looks as follows:
Copy-Item -Path $file -Destination "\\$computername\c$\windows\temp\installer.exe"
Invoke-Command -ComputerName $computerName -ScriptBlock {
c:\windows\temp\installer.exe /silent
}
Neither of these 2 commands works for me. Running the copy-item command returns The network path was not found. I can confirm that both the computer as well as the user have read access to the respective share.
Running the invoke-command command doesn't return any errors but nothing happens on the computer in question.
Marquette goes on to describe another way of doing the same, using a Remote Session:
$session = New-PSSession -ComputerName $computerName
Copy-Item -Path $file -ToSession $session -Destination 'c:\windows\temp\installer.exe'
Invoke-Command -Session $session -ScriptBlock {
c:\windows\temp\installer.exe /silent
}
Remove-PSSession $session
This, on the other hand, works perfectly. Any hint you can give me as to why this works but the other way doesn't?
Trying to configure remote PowerShell access on a server but cannot avoid access denied errors.
What I have done:
Register-PSSessionConfiguration
-Name EngrStudentAdmin
-RunAsCredential domain\delegatedAdmin
-StartupScript 'C:\Scripts\Students\Welcome.ps1'
-ShowSecurityDescriptorUI
(on a single line - displaying above for readability)
Using the permissions GUI, I granted the group DelegatedAdmins Read and Execute permissions. The startup script is just filler.
$welcome = 'Welcome to ' + $env:COMPUTERNAME
Write-Host $welcome
Attempting to connect to the endpoint with
Invoke-Command
-ComputerName $server
-ConfigurationName EngrStudentAdmin
-ScriptBlock { hostname }
fails with the error
AuthorizationManager check failed.
+ CategoryInfo : OpenError: (engr-mgr1.domain.edu:String) [], RemoteException
+ FullyQualifiedErrorId : PSSessionStateBroken
The execution policy on the server is RemoteSigned and the startup script is signed.
The account used to access the server is a member of the DelegatedAdmins group.
Opening a local shell as delegatedAdmin shows that the account has permission to run the startup script.
Using a member of the local admins group, the Invoke-Command, without the ConfiguationName switch (i.e. connecting to the default endpoint), executes so the winrm service is running and PSRemoting enabled.
The delegatedAdmin account has no profile.
What am I missing?
Check that the WMI service is enabled and running, if it's disabled try starting it and then retrying.
Also check the properties of the actual file, it might have been blocked.
are both Domain joined? If not you might take several further steps.
In general: Try this on the remote system: Enable-PSRemoting -Force -Verbose If you see nothing, it was already applied. If not, this will make alle necessary changes for you.
Just in case: Check your Firewall settings :-)
As Dewi mentioned: Check the WMI Service.
Here is a quick hack to enable it (if you want to enforce it):
# Configure WMI
Set-Item -Path wsman:\localhost\client\trustedhosts -Value * -Force -Confirm:$False
# Restart
Restart-Service -Name WinRM -Force
Last but not least: Use the -verbose switch to see more details.
Like this:
New-PSSession -ComputerName $ComputerName -Credential $credencial -Verbose
Cheers
Josh
I am making connection to the diferent system using powershell. I want this process to be automated in a way that once user hits the powershell script he gets connected to different system without entering username and password details into the dialog box. So, currently my.PS1 script as follows:
Enable-PSRemoting -Force
Set-Item wsman:\localhost\client\trustedhosts CP0001256
Restart-Service WinRM
Test-WsMan CP0001256
$credential = Import-CliXml -Path "D:\$Env:USERNAME_pass.xml"
Invoke-Command -ComputerName CP0001256-ScriptBlock { Get-ChildItem D:\ }-credential $credential
Before running my.PS1 i have executed follwing script:
$credential = Get-Credential
$credential | Export-CliXml -Path "D:\$Env:USERNAME_pass.xml"
So, when i execute my.PS1 i got error as:
Invoke-Command : Cannot process argument transformation on parameter 'Credential'. username
At my.PS1:7 char 86
+ Invoke-Command -ComputerName CP0001256-ScriptBlock { Get-ChildItem D:\ } -credential <<<< $credential
+ CategoryInfo : InvalidData: (:) [Invoke-Command], ParameterBindin..mationException
+ FullyQualifiedErrorID : ParameterArgumentTransformationError,Microsoft.Powershell.Commands.InvokeCommand
So, tell me what i am doing wrong and how can i avoid getting the credential dialog box pop up appearing.
This is a question of how to store credentials in a script. Keep in mind that this always carries some risk. You can of course store them in plain text. Then anyone with access to the script has those credentials.
Another thing you can do is take advantage of the [PSCredential] object, and store the password encrypted. Consider running this code (outside of that script):
$credential = Get-Credential # dialog pops up here, enter server creds
$credential | Export-CliXml -Path "C:\Script\$Env:USERNAME_Credential.xml"
Now in your script, you can do this:
$credential = Import-CliXml -Path "C:\Script\$Env:USERNAME_Credential.xml"
Invoke-Command -ComputerName CP0001256-ScriptBlock { Get-ChildItem D:\ }-credential $credential
The password is encrypted within that XML file, and it's encrypted with a key that is specific to the user who ran the first set of commands, so only that user will be able to effectively run the script if you do this.
This is also why I use the USERNAME environment variable as part of the file name. You can have multiple employees run the first code snippet to generate a separate encrypted file for each of them. Then your script will work successfully when any of them run it.
It also works if you have an account used for a scheduled task for example; run the snippet as that user once, then the scheduled task will work.