Windows PowerShell authentication - powershell

I am running PowerShell 1.0 under Windows XP, attempting to connect to machines running XP, Vista, and Server 2003 with the following command:
gwmi -cl Win32_OperatingSystem -co COMPUTER -n "root\CIMV2" -cr DOMAIN\ADMIN
This returns an error. "Exception retrieving members: Access is denied.".
gwmi -cl Win32_OperatingSystem -co COMPUTER -cr DOMAIN\ADMIN
This works.
Firewall and DCOM services are configured properly, otherwise neither command would not run.
I have tried the first command with credentials set to COMPUTER's local administrator, same error.
I can run the first command against localhost, no error.
$q = "Select * from Win32_OperatingSystem"
$y = [WmiSearcher] $q
$y.Scope.Path = "\\COMPUTER\root\cimv2"
$y.Scope.Options.Authentication = 6
$os = $y.Get()
also fails. The administrator group on COMPUTER has the appropriate permissions according to this Microsoft KB article.
We recently rolled out a WSUS server, pushing out a ton of miscellaneous Windows Updates to our systems. Are any updates known to break WMI like this?

I wonder if the remote side is requiring an encrypted connection for this particular namespace.
See if this approach works for you:
$q = "Select * from Win32_OperatingSystem"
$y = [WmiSearcher] $q
$y.Scope.Path = "\\<remote_computer_name>\root\cimv2"
$y.Scope.Options.Authentication = 6
$os = $y.Get()
Here is a link related to this issue.

Related

How to start a process on remote computer using powershell WMI?

We are upgrading our servers and need to stop our application before we perform update and then start it back again.
I was reading online about this and most of the links talk about remoting but some of the machines don't have PSRemoting enabled and therefore I need to stick to using wmi.
Would appreciate some pointers on this ?
To terminate the process I am using something like below:
$processes=Get-WmiObject -Class Win32_Process -ComputerName $Address -Filter "name='$ProcessName'"
foreach ($process in $processes)
{
$returnval = $process.terminate()
$processid = $process.handle
if($returnval.returnvalue -eq 0) {
write-host "The process $ProcessName `($processid`) terminated successfully"
}
else {
write-host "The process $ProcessName `($processid`) termination has some problems"
}
}
You don't say what OS and PS version(s) you are trying to deal with.
You are not saying what or if you are having issues with what you posted.
Even using only WMI, you still must have Windows WMI properly configured to do this as well as know Windows is not out of the boxed configured to let you what you are after without making all the proper WinRM, WMI and firewall manual configs.
It's far simpler just to enable PSRemoting via GPO.
Otherwise, you will need tp look toward maybe winrs.exe or MS SysInternals psexec.
winrs
Windows remote Management allows you to manage and execute programs remotely.
PsExec v2.2
Also back to my what OS and PowerShell version you are using. There is the
Invoke-Wmi​Method
Which can lead to stuff like this ---
Invoke-WmiMethod -ComputerName $TargetMachine -Namespace root\cimv2 -Class Win32_Process..."

Use Powershell to install windows Patches

I already tried alot of tips on Stackoverflow, but nothing seems to work.
If I run this Code a Window Pops up.
The PowerShell Version is 2.0
My Code:
$PATH = "S:\User\Person\UPDATES\Update for Windows 7 for x64-based Systems (KB3134760)\AMD64-all-windows6.1-kb3134760-x64_d720851ef4b5a37c1c8bdd2e5bf4c77dcc625e8c.msu"
$SB = {Start-Process -FilePath 'c:\windows\system32\wusa.exe' -ArgumentList ('S:\User\Voss\UPDATES\Update for Windows 7 for x64-based Systems (KB3134760)\AMD64-all-windows6.1-kb3134760-x64_d720851ef4b5a37c1c8bdd2e5bf4c77dcc625e8c.msu','/quiet', '/promtrestart', "/log:S:\User\Voss\UPDATES\Update for Windows 7 for x64-based Systems (KB3134760)\Update.log") -Wait}
$computer = echo (Get-WmiObject -Class Win32_ComputerSystem -Property Name).Name
Invoke-Command -ScriptBlock $SB
First off, E.D. (hehe) is correct about your spelling error. A simple syntax error can break even the most otherwise elegant/complex scripts.
You're going to a lot of additional trouble to install patches from what I'm assuming is a (remote) mapped drive. If you're trying to do this on other machines, you'll want to use something like psexec or a scheduled task to kick off the install under the machines' credentials (NT Authority\System). If you're doing this on your machine and FOR your machine.
Picking your code apart:
$PATH = "S:\User\Person\UPDATES\Update for Windows 7 for x64-based Systems (KB3134760)\AMD64-all-windows6.1-kb3134760-x64_d720851ef4b5a37c1c8bdd2e5bf4c77dcc625e8c.msu"
$SB = {Start-Process -FilePath 'c:\windows\system32\wusa.exe' -ArgumentList ('S:\User\Voss\UPDATES\Update for Windows 7 for x64-based Systems (KB3134760)\AMD64-all-windows6.1-kb3134760-x64_d720851ef4b5a37c1c8bdd2e5bf4c77dcc625e8c.msu','/quiet', '/promtrestart', "/log:S:\User\Voss\UPDATES\Update for Windows 7 for x64-based Systems (KB3134760)\Update.log") -Wait}
$computer = echo (Get-WmiObject -Class Win32_ComputerSystem -Property Name).Name
Invoke-Command -ScriptBlock $SB
1) I don't really understand what you're doing with the $PATH variable as it isn't referenced anywhere else.
2) $SB doesn't 'REALLY' need to be delimited that way, but should work. Normally, I would just make it a single string and, when referencing other variables, utilize this syntax to get them to be evaluated first - $($PATH)
3) for $computer, you're kind of right. Lose the echo and you should be fine since you're just getting the name of the local machine ( $Env:ComputerName would work just as well and be more economical even if you're running the code on another machine, IMHO )
Addressing the use case where you might be running this code on another machine:
You seem to be assuming that you are logged on and your drive mapping is applicable. If you're accessing a network share, you'd want to make sure the remote machine has read permissions to the share so it could get to the file(s) in question and you'll also want to use the UNC path for simplicity's sake. This is a situation where psexec \ -S WUSA \UNC PATH\To\Update\File.msu would be best utilized.
Bottom line, if you'd communicate what your intent is a bit better, I might be better able to assist.

How to retrieve xenstore parameters from WMI interface

I'm trying to retrieve some parameters from xenstore using WMI (specifically, I was hoping to use this script to change a VM IP address after it's created).
According to this article, it seems like I should just be able to do something like:
From the xenserver CLI:
xe vm-param-set uuid=e66660e9-85e1-1f99-3229-1dfa7d1065a8 xenstore-data:data/TempValue=test
then in a powershell script:
$base = gwmi -n root\wmi -cl CitrixXenStoreBase
$sid = $base.AddSession("MyNewSession")
$session = gwmi -n root\wmi -q "select * from CitrixXenStoreSession where SessionId=$($sid.SessionId)"
$output = $session.GetValue("data/TempValue").value
log "$output"
But that doesn't seem to retrieve the value that I expect.
One thing I noticed was if I set the value from a powershell script, it seems to consistently retrieve the value when I run the previous script:
$base = gwmi -n root\wmi -cl CitrixXenStoreBase
$sid = $base.AddSession("MyNewSession")
$session = gwmi -n root\wmi -q "select * from CitrixXenStoreSession where SessionId=$($sid.SessionId)"
$session.SetValue("data/TempValue","This is a string")
It seems to retain the set value across sessions, but when I go back to the CLI and attempt to find the value, I get nothing:
xe vm-param-list uuid=e66660e9-85e1-1f99-3229-1dfa7d1065a8 | grep TempValue
So what it boils down to is that I'd like to either:
Know how to retrieve a xenstore parameter in a WMI script after executing the xe vm-param-set command.
Know how to set a parameter in the xenserver CLI in the same way that $session.SetValue works in the above example.
Nevermind, looks like this was user error on my end. I was setting the values after the VM was already started. Looks like the parameters have to be set before the VM starts (or the VM should be restarted).

Grabbing system product keys

So I'm trying to use the PS script found at http://gallery.technet.microsoft.com/scriptcenter/Get-product-keys-of-local-83b4ce97#content to pull Windows product keys from my domain remotely. However, when it hits a host it returns Exception calling “OpenRemoteBaseKey” with “2″ argument(s): “The network path was not found” instead of the product key. It should also be noted that this works locally. After poking around at the internals of the script, it seems like the offending line is
$remoteReg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$Computer)
Research (because I'm totally new to PoSH) indicates that this type of error gets thrown when remote registry access isn't working. Trying to hook into the registry on my test target via regedit shows that I need to have Windows Firewall: Allow inbound remote administration exception set to enabled in Group Policy. I set it and then pulled the updated policy down to the same result. What other stuff might be getting in the way of my connection?
I would recommend using PSRemoting over using the remote registry. Assuming this is set up, all you would have to do is:
$computers = #('localhost')#list of computers
#unless you are currently logged in as a domain admin
# you will need to provide credentials
$cred = Get-Credential domain\administrator
Invoke-Command -Credential $cred -ComputerName $computers -ScriptBlock {
function Get-ProductKey{
#from http://gallery.technet.microsoft.com/scriptcenter/Get-product-keys-of-local-83b4ce97
}
get-ProductKey
}| ft Computername,OSDescription,OSVersion,ProductKey
This will print out the following output:
Computername OSDescription OSVersion ProductKey
------------ ------------- --------- ----------
%name% Microsoft Windows 8 Pro 6.2.9200 XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
I used the following command through powershell, ran it as admin:
wmic /user:jc1_admin /node:pc00202 os get "SerialNumber"

Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)

When I run
Get-WmiObject win32_SystemEnclosure -Computer hostname | select serialnumber
it works for both local and remote hosts.
When I do this for a list of hosts using
ForEach ($_ in gc u:\pub\list.txt) {
Get-WmiObject win32_SystemEnclosure -Computer $_ | select serialnumber | format-table -auto #{Label="Hostname"; Expression={$_}}, #{Label="Service Tag"; Expression={$_.serialnumber}}
}
it returns
Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
Check that the "Windows Management Instrumentation (WMI-In)" rule is enabled in the firewall for each remote machine.
Or in an Administrative Command/Powershell prompt run:
netsh advfirewall firewall set rule group="Windows Management Instrumentation (WMI)" new enable=yes
It might be due to various issues.I cant say which one is there in your case.
Below given reasons may be there:
DCOM is not enabled in host PC or target PC or on both.
Your Firewall or even your antivirus is preventing the access.
Any WMI related service is disabled.
Some WMI related services are as given:
Remote Access Auto Connection Manager
Remote Access Connection Manager
Remote Procedure Call (RPC)
Remote Procedure Call (RPC) Locator
Remote Registry
For DCOM setting refer:
Key: HKLM\Software\Microsoft\OLE, Value: EnableDCOM
The value should be set to 'Y' .
Your code probably isn't using a correct machine name, you should double check that.
Your error is:
Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
This is the result you get when a machine is not reachable. So the firewall suggestions are reasonable, but in this case probably not correct because you say this works:
Get-WmiObject win32_SystemEnclosure -Computer hostname
So in your case it seems when this line is executed:
Get-WmiObject win32_SystemEnclosure -Computer $_
$_ doesn't contain a proper computer name. You could check type and contents of $_. Probably there is a problem with the file contents. If the file looks right, then maybe the lines are not properly terminated. You can take a closer look using Write-Host:
ForEach ($_ in gc u:\pub\list.txt) {
Write-Host "Get-WmiObject win32_SystemEnclosure -Computer '$_'"
Get-WmiObject win32_SystemEnclosure -Computer $_ | select serialnumber | format-table -auto #{Label="Hostname"; Expression={$_}}, #{Label="Service Tag"; Expression={$_.serialnumber}}
}
I was having the same problem but only with a few machines. I found that using Invoke-Command to run the same command on the remote server worked.
So instead of:
Get-WmiObject win32_SystemEnclosure -ComputerName $hostname -Authentication Negotiate
Use this:
Invoke-Command -ComputerName $hostname -Authentication Negotiate -ScriptBlock {Get-WmiObject win32_SystemEnclosure}
If you've tried some of the suggestions in the other answers, most notably:
David Brabant's answer: confirming the Windows Management Instrumentation (WMI) inbound firewall rule is enabled
Abhi_Mishra's answer: confirming DCOM is enabled in the Registry
Then consider other common reasons for getting this error:
The remote machine is OFF
You specified an invalid computer name
There are network connectivity problems between you and the target computer
Solved.
I was running into the exact same error message when trying to execute the following script (partial) against a remote VM that was configured to be in the WORKGROUP.
Restart-Computer -ComputerName MyComputer -Authentication Default -Credential $cred -force
I noticed I could run the script from another VM in the same WORKGROUP when I disabled the firewall but still couldn't do it from a machine on the domain. Those two things along with Stackflow suggestions is what brought me to the following solution:
Note: Change these settings at your own risk. You should understand the security implications of these changes before applying them.
On the remote machine:
Make sure you re-enable your Firewall if you've disabled it during testing.
Run Enable-PSRemoting from PowerShell with success
Go into wf.msc (Windows Firewall with Advanced Security)
Confirm the Private/Public inbound 'Windows Management Instrumentation (DCOM-In)' rule is enabled AND make sure the 'Remote Address' property is 'Any' or something more secure.
Confirm the Private/Public inbound 'Windows Management Instrumentation (WMI-In)' rule is enabled AND make sure the 'Remote Address' property is 'Any' or something more secure.
Optional: You may also need to perform the following if you want to run commands like 'Enter-PSSession'.
Confirm the Private/Public inbound 'Windows Management
Instrumentation (ASync-In)' rule is enabled AND make sure the
'Remote Address' property is 'Any' or something more secure.
Open up an Inbound TCP port to 5985
IMPORTANT! - It's taking my remote VM about 2 minutes or so after it reboots to respond to the 'Enter-PSSession' command even though other networking services are starting up without problems. Give it a couple minutes and then try.
Side Note: Before I changed the 'Remote Address' property to 'Any', both of the rules were set to 'Local subnet'.
I found this blog post which suggested adding a firewall exception for "Remote Administration", and that worked for us on our Windows Server 2008 Enterprise systems.
http://mikefrobbins.com/2012/03/08/get-wmiobject-the-rpc-server-is-unavailable-exception-from-hresult-0x800706ba/
Enabling following FW rules on target system resolved the problem on Win2k16:
Windows Management Instrumentation (WMI-In)
Distribiuted Transaction Coordinator (RPC)
Distribiuted Transaction Coordinator (RPC-EPMAP)
I was having the same issue using foreach. I saved the list to $servers and used this which worked:
ForEach ($_ in $Servers) { Write-Host "Host $($_)" | Get-WmiObject win32_SystemEnclosure -Computer $_ | format-table -auto #{Label="Service Tag"; Expression={$_.serialnumber}}
}
Thought I would add that we also ran into this issue with multiple machines in our domain. I created a list of offending machines and added them all to a text file from which to run the script. I ran this from the CMD prompt using elevated privileges.
psexec #firewallFix.txt -d netsh advfirewall firewall
set rule name="Windows Management Instrumentation (WMI-In)"
profile=domain new enable=yes profile=domain
I had same issue, and for me, I was trying to use an IP Address instead of computer name.
Just adding this as one more potential solution for people finding this down the road.
I faced the similar issue on new server that I built through automated scripts via vcenter api. Looks like the "Remote Procedure Call (RPC)" service may not be running on the remote machine. you need to wait for the service to come up to use the Get-WmiObject command. Hence I simply put the script into sleep for sometime and it worked.
Below is the native PowerShell command for the most up-voted solution.
Instead of:
netsh advfirewall firewall set rule group="Windows Management Instrumentation (WMI)" new enable=yes
Use could use the slightly simpler syntax of:
Enable-NetFirewallRule -DisplayGroup "Windows Management Instrumentation (WMI-In)"
Very odd but I used the IP address (vs the hostname) and it worked for me.
Get-WmiObject -Computername MyHostName ...
[Fails: Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)]
Get-WmiObject -Computername 50.50.50.50
[Successful]
I encountered the same "Exception from HRESULT: 0x800706BA" error with get-wmiobject -computerName remoteserverName -class win32_logicaldisk. The remote server is an AWS EC2 instance in my case. The Windows server firewall has WMI ports open. SecurityGroup attached to the EC2 instance has common RPC ports (tcp/udp 135-139, 49152 - 65535) inbound allowed.
I then ran netstat -a -b |findstr remoteServerName after kick off the get-wmiobject powershell command. Turns out the command was trying hit tcp port 6402 on the remote server! After added tcp 6402 into its Security Group inbound rule, get-wmiobject works perfectly! It appears the remote server has WMI set to a fixed port!
So if you checked all usual firewall rules and stil having problem with WMI, try use netstat to identify which port the command is actually trying to hit.
I thought I would add another thing to try. If someone has multiple domains you could try using fully qualified domain names: computer1.subdomain.domain.com
Port 135 will be used by RPC client- server communication.
So Make sure that port 135 is not blocked by your local firewall. It may be one of the reasons for not working.
Here's a link that could help you: https://www.dell.com/support/kbdoc/en-in/000179474/troubleshooting-rpc-server-unavailable-errors
Turning the firewall off resolved it for me.
I was doing this mistake
ForEach ($server in $servers) {
$OS = Get-WmiObject win32_operatingsystem -ComputerName $server
}
Which, of course, couldn't be passed, because output of the server in a csv file was #{Name=hv1g.contoso.com}
I had to call the property from csv file like this $server.Name
ForEach ($server in $servers) {
$OS = Get-WmiObject win32_operatingsystem -ComputerName $server.Name
}
It fixed my issue.
I just came to the exact same issue and found the answer here: http://powershellcommunity.org/Forums/tabid/54/aft/7537/Default.aspx
I had space characters at the end of each line the input file. If your file does too, just remove them and your script should work.