I have an old established codebase that I'm trying to bring up to modern era standards. Most of it is written on Windows using Visual Studio, so I need to have a Windows based build server to use the MSBuild pipeline. I have a mostly working Jenkins CI pipeline that ingests from Github webhooks, and should deploy to a Windows PC on my local network. I've tested that this works from any other user, on my workstation and on the build server. I know Jenkins runs jobs as the "NT AUTHORITY\System" user, and I've used SysInternals PSExec to pop in and setup my ssh keys, and so forth in the past. The problem is during the deploy step; I'm compressing and copying the build output using a PowerShell script, and using New-PSSession, and Copy-Item -ToSession.
I'm using a cred I'm constructing with Get-Credential, user/pass pair, that I've verified as working. All concerned systems are in a simple workgroup, no domain involved.
The New-PSSession command in my deploy.ps1 script fails with the following error:
PS C:\Program Files (x86)\Jenkins\workspace\xxx> .\deploy.ps1
Compressing to C:\Windows\TEMP\tmpEBB2.tmp.zip
New-PSSession: C:\Program Files (x86)\Jenkins\workspace\xxx\deploy.ps1:95
Line |
95 | … $sess = New-PSSession -ComputerName $TargetHost -Credential $cred …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| [205.208.87.185] Connecting to remote server 205.208.87.185 failed with the following error message :
| WinRM cannot process the request. The following error with errorcode 0x8009030d occurred while using
| Negotiate authentication: A specified logon session does not exist. It may already have been
| terminated. Possible causes are: -The user name or password specified are invalid. -Kerberos is
| used when no authentication method and no user name are specified. -Kerberos accepts domain user
| names, but not local user names. -The Service Principal Name (SPN) for the remote computer name and
| port does not exist. -The client and remote computers are in different domains and there is no trust
| between the two domains. After checking for the above issues, try the following: -Check the Event
| Viewer for events related to authentication. -Change the authentication method; add the destination
| computer to the WinRM TrustedHosts configuration setting or use HTTPS transport. Note that computers
| in the TrustedHosts list might not be authenticated. -For more information about WinRM
| configuration, run the following command: winrm help config. For more information, see the
| about_Remote_Troubleshooting Help topic. Other Possible Cause: -The domain or computer name was not
| included with the specified credential, for example: DOMAIN\UserName or COMPUTER\UserName.
Write-Error: C:\Program Files (x86)\Jenkins\workspace\xxx\deploy.ps1:129
Line |
129 | Deploy-ToTargetHost
| ~~~~~~~~~~~~~~~~~~~
| Could not establish session.
I generated that second error when the $sess var fails to populate. This is line 95:
$sess = New-PSSession -ComputerName $TargetHost -Credential $cred
I believe I've heard something about the System user has some restrictions on network access? Is there any way to work around this?
I mean, I can just scp it over if there's no other way to do this, but I really wanted to just have all my shell scripting in pwsh if I could get away with it. Thanks.
[Edit: TL;DR, I suppose I can modify Jenkins to run as a different user, but why isn't it already running like that? This just seems trivially weird to me to install by default on a user with no network access, I guess?]
I ended up running Jenkins as a different user in Windows Services, specifically a "regular" login user. This made it do the deployment successfully.
i have an problem with my script, plz help :3
This script is supposed to get all Server Hostnames from our Server OU. And than get the Used and Free Space of the Servers But when i try to get the server list with the "Get-AdComputer" cmdlet i get errors.
$servers = Get-ADComputer -Filter * -SearchBase "OU=SomeOU, DC=SomeDomain, DC=SomeDomain, DC=SomeDomain" | Select-Object Name
$allDisks = foreach ($server in $servers)
{
Get-WmiObject Win32_LogicalDisk -ComputerName $server -Filter DriveType=3 |
Select-Object #{'Name'='ComputerName'; 'Expression'={$server}},
DeviceID,
#{'Name'='Size'; 'Expression'={[math]::truncate($_.size / 1GB)}},
#{'Name'='Freespace'; 'Expression'={[math]::truncate($_.freespace / 1GB)}}
}
$allDisks |Export-Csv C:\Servers.csv -NoTypeInformation
when i run this i get:
Get-WmiObject : Der RPC-Server ist nicht verfügbar.
In Zeile:5 Zeichen:5
+ Get-WmiObject Win32_LogicalDisk -ComputerName $server -Filter Dri ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
i also should add, that if i only run the thing from the first line i get an clean list of all of our servers.
As the error states that RPC server is not available for the one of the servers that you are trying to query. There can be multiple reasons as per the PS Blog:
The remote computer is blocked by the firewall.
Solution: Open the Group Policy Object Editor snap-in (gpedit.msc) to edit the Group Policy object (GPO) that is used to manage Windows Firewall settings in your organization. OpenComputer Configuration, open Administrative Templates, open Network, open Network Connections, open Windows Firewall, and then open either Domain Profile or Standard Profile, depending on which profile you want to configure. Enable the following exception: “Allow Remote Administration Exception” and “Allow File and Printer Sharing Exception“.
Hostname or IP address is wrong or the remote computer is shut down.
Solution: Verify correct hostname or IP address.
The “TCP/IP NetBIOS Helper” service isn’t running.
Solution: Verify that “TCP/IP NetBIOS Helper” is running and set to auto start after restart.
The “Remote Procedure Call (RPC)” service is not running on the remote computer.
Solution: Verify that “Remote Procedure Call (RPC)” is running and set to auto start after restart.
The “Windows Management Instrumentation” service is not running on the remote computer.
Solution: Verify that “Windows Management Instrumentation” is running and set to auto start after restart
So, I dont think there is any code issue there. Kindly check the network firwwall and server side. Also apply a try/catch block and capture the exact server name in the loop to see which server is that causing the issue.
I created a new Virtual Machine in Azure. (Windows Server 2016 Datacenter Server Core)
The VM creation process allowed me to enable SSH access (and I did):
Image of VM Creation Wizard
However I find myself unable to establish a SSH connection to the Windows Server.
I learned that in situations like this, it is sometimes necessary to reset the "configuration password":
"Reset Password" for VM
This action allowed me to successfully use the "troubleshoot the connection" tool (built into Azure) to "stage" a SSH connection (from my IP to the Azure VM). However I still find myself unable to establish a SSH connection. (The connection continues to "time out".)
Image of Inbound Network Rules
Image of Azure "Connection troubleshooter"
Any ideas?
I had to follow these instructions to manually install the sshd service:
https://365adviser.com/powershell/install-use-openssh-windows-powershell-core-remoting-via-ssh/
It's worth noting that Step #2 refers to a depreciated GitHub project. As such I needed to tweak the URI. I also needed to append the the -UseBasicParsing option. Here is the final result:
Invoke-WebRequest -Uri http://mengelsen.000webhostapp.com/shared-items/OpenSSH-Win64.zip -UseBasicParsing -OutFile openssh.zip
Does windows command line requires any proxy setting to ping websites?
I can access all websites in my browser but when I try to ping the same from commandline or powershell I get "Request timed out" error. How to resolve this error?
In IE browser I've set a automatic proxy detection script as the network is company LAN. Tried most of solutions provided in web without any luck.
Due to this I am unable to run the chef commands to install gems and receiving error Unable to download data from https://rubygems.org/ - Errno::ETIMEDOUT:
A connection attempt failed because the connected party did not properly respon
d after a period of time, or established connection failed because connected hos
t has failed to respond. - connect(2) for "api.rubygems.org" port 443 (https://a
pi.rubygems.org/specs.4.8.gz)
Getting a ping reply or HTTP response are two entirely different things. That is, any server can honor either of those just as well as it pleases. In addition, there might be proxies and firewalls on the route that change the results. Even if a server is willing to reply on ping, corporate firewall might block it.
You might have some success with setting Chef's proxy settings via environment variables, as per documentation. As how to find out the proxy settings, ask your network admin. If that doesn't work, retrieve the proxy settings from IE's registry key. In case of link rot, here's the function:
function Get-InternetProxy {
<#
.SYNOPSIS
Determine the internet proxy address
.DESCRIPTION
This function allows you to determine the the internet proxy address used by your computer
.EXAMPLE
Get-InternetProxy
.Notes
Author : Antoine DELRUE
WebSite: http://obilan.be
#>
$proxies = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings').proxyServer
if ($proxies) {
if ($proxies -ilike "*=*") {
$proxies -replace "=","://" -split(';') | Select-Object -First 1
} else {
"http://" + $proxies
}
}
}
I can't seem to get access to a webpage using Powershell. I keep getting a "(407) Proxy Authentication Required". I've tried many things. I don't know what the proxy is or what kind of authentication it requires. The only thing I have access to is in IE it uses a script for configuring. I tried using some IPs from that, but no luck. Any ideas?
Here is one example of what I tried:
$wc = New-Object System.Net.WebClient
$wc.Headers.Add("User-Agent","Mozilla/4.0+")
$wc.Proxy = [System.Net.WebRequest]::DefaultWebProxy
$wc.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$wc.DownloadString("http://stackoverflow.com")
I had a similar issue and resolved it with just two lines of powershell:
$browser = New-Object System.Net.WebClient
$browser.Proxy.Credentials =[System.Net.CredentialCache]::DefaultNetworkCredentials
I haven't seen anyone doing something like this but there is a way to do this as a "global setting" in your Powershell script (I remember doing this in C# before for local dev builds).
[System.Net.WebRequest]::DefaultWebProxy = [System.Net.WebRequest]::GetSystemWebProxy()
[System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
This way if you don't want to update all your WebClients with proxy details, you can just override the global setting (have to be done every time you run the script).
But this assumes that the current logged in Windows user is valid for the system-defined proxy server.
NOTE: I would say that this is only useful as a quick and dirty way to get a PS script working that wasn't proxy aware before (like Cake build).
If the proxy answers "407", "proxy authentication required", then the authentication is required:
$Username="Hugo"
$Password="abcdefgh"
$WebProxy = New-Object System.Net.WebProxy("http://webproxy:8080",$true)
$url="http://aaa.bbb.ccc.ddd/rss.xml"
$WebClient = New-Object net.webclient
$WebClient.Proxy=$webproxy
$WebClient.proxy.Credentials = New-Object System.Net.NetworkCredential($Username, $Password)
$path="C:\Users\hugo\xml\test.xml"
$WebClient.DownloadFile($url, $path)
Content now resides in "test.xml"
I know the question is specifically about Powershell 2.0, but I would like to share information on setting up a proxy server in Powershell Core (6+) because it's extremely hard to find elsewhere.
I agree with Dandré, that the best solution is to configure the default proxy server. I just had an issue with Powershell Core (7.1). I was trying exactly what Dandré suggests, but it didn't have any effect. After several hours of research and investigation, I have found out that Powershell Core is probably not using System.Net.WebRequest to make web requests anymore, but rather System.Net.Nett.HttpClient.
When I have configured the HttpClient's default proxy server, all web connections made by Powershell (Invoke-WebRequest, PowerShellGet's Find-Module, Install-Module, etc.) finally started to work.
Configure Default Proxy Server for Powershell Core
If you need to make the configuration permanent, just add the commands below to your Powershell profile.
Configure a specific default proxy server
[System.Net.Http.HttpClient]::DefaultProxy = New-Object System.Net.WebProxy('http://your-proxy')
If you need to set a specific port, add it to the proxy server URI: http://proxy:1234.
Configure credentials for authenticating proxy
In case it's an authenticating proxy, you need to set up the credentials to be used for proxy authentication. Use the following command to set the credentials of your domain account under which you're currently logged in to Windows:
[System.Net.Http.HttpClient]::DefaultProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
If you need different credentials, you can use the Get-Credential cmdlet, but it's interactive so it's not an ideal solution to have in your Powershell profile. But I'm sure there're other ways.
[System.Net.Http.HttpClient]::DefaultProxy.Credentials = Get-Credential
Configure proxy server bypassing
If you just need to bypass the proxy server and use the direct connection, but Powershell is using the default system-wide proxy server, simply set the HttpClient's default proxy to null:
[System.Net.Http.HttpClient]::DefaultProxy = New-Object System.Net.WebProxy($null)
Add Proxy Configuration to Powershell Profile
To make the configuration permanent, simply add the commands you need to your Powershell profile. There're four of them (All users, all hosts; All users, current host; Current user, all hosts; Current user, current host), but I would use the "Current user, all hosts". To find out the location of a specific profile, use the $Profile variable with a profile name:
$Profile.CurrentUserAllHosts
It should print the path $Home\Documents\Powershell\profile.ps1.
If the profile doesn't exist yet, just create it and put the configuration there. It will be executed every time you execute a new Powershell Core (pwsh.exe) instance.
Configure Default Proxy using Environment Variable
An alternative solution is to use an environment variable. According to the documentation, HttpClient is actually using the following variables to initialize the default proxy if they're defined:
HTTP_PROXY for HTTP requests
HTTPS_PROXY for HTTPS requests
ALL_PROXY for both HTTP and HTTPS
NO_PROXY may contain a comma-separated list of hostnames excluded from proxying
An example usage:
ALL_PROXY='http://proxy:1234'
And if you need to pass credentials:
ALL_PROXY='http://username:password#proxy:1234'
This solution is supported by a wider range of applications, so if it's better or worse than the previous solution depends on what exactly you want to configure, just Powershell or also other applications.
If you use the following you'll receive a prompt to enter your credentials:
$client.Credentials = Get-Credential
I solved this with just three lines:
$proxy='http://username:password#IP:PORT'
$ENV:HTTP_PROXY=$proxy
$ENV:HTTPS_PROXY=$proxy
If you know the script - just download it, open with Notepad and find IP and port of your proxy server. As for authentication - most probably your windows credentials are used, so in theory you should be able to keep it empty, unless there's something suspicious in the script.
try adding cache credentials....
$domain = 'ChDom'
$Client = new-object System.Net.WebClient
$cc = New-object System.Net.CredentialCache
$urlObj = New-object System.Uri($url)
#these variables must be plaintext strings
$creds = New-object System.Net.NetworkCredential($Username,$Password)
#your auth might be different than mine
$cc.add($urlobj,"NTLM",$creds)
$client.Credentials = $cc
$Client.Downloadfile($url, C:\Temp\TestPage.html)
Option 1 - Setting Proxy Authentication via Code.
Another Authenticated Proxy Example With Credentials
# 1). Set your http proxy address and port
$proxy = New-Object System.Net.WebProxy("http://p.weshare.net:80",$true)
# 2). Set your http proxy credentials
$proxy.Credentials = New-Object System.Net.NetworkCredential("username", "password")
# 3). Set the global proxy
[System.Net.WebRequest]::DefaultWebProxy = $proxy
# 4). sets a value that indicates whether to bypass the proxy server for local addresses.
[System.Net.WebRequest]::DefaultWebProxy.BypassProxyOnLocal = $true
# 5). Call Invoke-WebRequest without -Proxy Tag ( as it pulls it from what you defined )
$reposnseText = Invoke-WebRequest https://www.oracle.com
Just wrapping it as a Function
Function Set-My-Proxy
{
param($proxy,$username,$password)
$proxy = New-Object System.Net.WebProxy($proxy,$true)
$proxy.Credentials = New-Object System.Net.NetworkCredential($username, $password)
[System.Net.WebRequest]::DefaultWebProxy = $proxy
[System.Net.WebRequest]::DefaultWebProxy.BypassProxyOnLocal = $true
}
Call the Function
Set-My-Proxy 'http://p.weshare.net:80' 'username' 'password'
Option 2 - Setting Proxy Authentication via Another Proxy
Credits & Limitations of solution
Install local proxy, e.g : squid for windows
After installing, open squid.conf file ( right mouse click on squid icon on task bar -> Open Squid Configuration
Put the following code
please provide authenticated proxy ip only ( in our example : 10.1.2.3 - not domain one )
http_access allow all
http_port 3128
coredump_dir /var/spool/squid3
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern (Release|Packages(.gz)*)$ 0 20% 2880
refresh_pattern . 0 20% 4320
cache_peer 10.1.2.3 parent 80 0 no-query default login=my_username:my_password
never_direct allow all
access_log none
cache_log none
Restart Squid Service
You now may call your local proxy, which will forward request to authenticated proxy and response back
Invoke-WebRequest -Uri 'https://stackoverflow.com/' -Proxy 'http://127.0.0.1:3128'