Powershell Remote: Microsoft.Update.Session, Access Denied: 0x80070005 - com

I've written a script to search/download/install Windows Updates on a machine using the Microsoft.Update.Session COM Object. When run locally it works just fine, however when running through a remote session or through Invoke-Command I receive an access denied (0x80070005) error on Microsoft.Update.Session.CreateUpdateDownloader()
I receive the same error if I attempt to create a Downloader object directly, code to reproduce the issue:
$oUpdateDownloader = new-object -com "Microsoft.Update.Downloader"
I am an administrator on the remote machine, and passing credentials (for myself explicitly or any other admin account) to the machine does not seem to change anything.
I've seen this error posted a number of times but there does not seem to be any information on solving the problem...
Any ideas?

When you are in a remote PowerShell session your logon session on this remote computer is flagged as a "network" logon (Logon Type: 3).
For some obscure (security? sell SCCM?) reason, part of the Windows Update Agent COM APIs are restricted to only be usable by locally logged on Administrators.
Using PsExec and Scheduled Tasks have been suggested as workarounds.
IMO, the most seamless (and still secureable) solution is to facilitate the RunAs-style "Local Virtual Account" feature of PowerShell Session Configurations / JEA.
Usually, JEA is used to "restrict" what a user can do on a remote computer PowerShell-wise, but we are (ab-)using it here to gain full access as if we were a locally logged on Administrator.
(1.) Create a new unrestricted (and persistent!) session configuration on ComputerB (remote server):
New-PSSessionConfigurationFile -RunAsVirtualAccount -Path .\VirtualAccount.pssc
# Note this will restart the WinRM service:
Register-PSSessionConfiguration -Name 'VirtualAccount' [-ShowSecurityDescriptorUI] -Path .\VirtualAccount.pssc -Force
# Check the Permission property:
Get-PSSessionConfiguration -Name 'VirtualAccount'
# Those users will have full unrestricted access to the system!
(2.) From ComputerA (local client) connect to our unrestricted session configuration on ComputerB:
New-PSSession -ComputerName 'ComputerB' -ConfigurationName 'VirtualAccount' | Enter-PSSession
[ComputerB]: new-object -com "Microsoft.Update.Downloader" # Yay!

This is a known issue. It appears that there is a bug with the actual COM object itself, as this issue occurs when using VBScript, PowerShell, and even C#. There is a good article that discusses managing Windows Update with PowerShell that can be found here.
The workaround is to set up a scheduled task on the computer and you can invoke that task however you see fit.

Use PsExec (http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx) to remotely execute PowerShell with a script file:
psexec -s \\remote-server-name C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe \\server\script.ps1
I used the script detailed at http://www.ehow.com/how_8724332_use-powershell-run-windows-updates.html, and I can remotely execute it using psexec to download and install updates.

the windows update code isn't callable form a remote machine. there are a few workarounds out on the web, including using psexec and a script (powershell or vbscript).
I used WUInstall myself and BoeProx has documented a few alternatives and has started a project PoshPAIG. I moved jobs before using this so don't know if it works.

The other solution is to change Windows registry setting using PowerShell and optionally restart wuauserv for the changes to take effect.
For example in Windows Server 2008R2 AutoUpdate settings can be found at:
HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update

Related

Testing if user created in AD can be logged into on a VM

I am a QA automation engineer and in the web app I test there's a feature that creates Active Directory users.
My tools are - Selenium (Java), RemoteWebDriver, Selenium Grid (Docker)
I was trying to find ways to validate this process and came to a stop - this field (AD) is new
to me and I need to find a way to make sure the user was created and can be logged into in the
network.
I was trying to find a way to do this and came up with 2 options, where the first one is the least
preferred way:
Make a request (API? 3rd side tool?) to get the relevant user(s).
The issue:
A user created and registered in the AD doesn't necessarily mean that the client can log into it (at least by the way I understood how AD works), and so it loses the most important consequence of the feature.
Use a VM, get the AD user information (username + password: possible) and try to log into the VM using those details.
The issue:
I haven't came across a tool that does it, the closest thing is Robot class or WinAppDriver.
WinAppDriver seems like the best solution as of now although I don't know how to make the login process work since it's the process starts before the desktop is open and I don't know how to locate the username and password field, so I figured using Robot class seems like the simplest solution, if it works on a VM that is, which as of now doesn't seem like it does.
So, before advancing on learning how to use WinAppDriver with my current automation, I'd like and appreciate your opinions about the matter or if you have simpler solutions.
Thank you very much for reading!
• We can check whether a user is created successfully or not and if that user can log in to the AD domain or not by executing a script as below. It is a powershell script that auto logs in through remote desktop protocol in the other domain joined VM from an Azure domain joined VM that checks whether the recently created user can login or not.
Powershell script : -
cmdkey /list | ForEach-Object{if($_ -like "*target=TERMSRV/*"){cmdkey /del:($_ -replace " ","" -replace "Target:","")}}
echo "Connecting to 192.168.1.100"
$Server="192.168.1.100"
$User="Administrator"
$Password="AdminPassword"
cmdkey /generic:TERMSRV/$Server /user:$User /pass:$Password
mstsc /v:$Server
• In the above script, replace the ‘$user’ value by the user principal name of the newly created user, i.e., ‘$User=”testdemo#example.com”’ and the ‘$Password’ value by the password set for that user. Also, ensure that you replace and enter the correct IP address of the domain controller/AD server. Also, ensure that before executing the above powershell script, execute the below commands in an elevated (administrator privileges) powershell console.
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
Lastly, please ensure that while creating the user, the option ‘User must change password at next logon’, ‘Account is Disabled’, ‘Password never expires’ and ‘User cannot change password’ are unchecked and not selected.
• Also, you can use the below command line script for logging in to the domain joined Azure VM through RDP protocol. In the below command, replace the ‘username’ and ‘password’ with the username and password of the user created recently to log in to the Azure VM with this command line script. Also, replace the ‘TERMSRC’ with the hostname of the server system or the domain joined VM where the specified UNC path is located and replace the ‘some_unc_path’ with the actual path UNC path of the shared directory folder. Please execute the below command through elevated (administrator privileges) command prompt.
Command script: -
c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -nolog -command cmdkey /generic:TERMSRC/some_unc_path /user:username /pass:pa$$word; mstsc /v:some_unc_path

Why a PowerShell command in a host is not returning the same thing as in the PowerShell console?

I am developing a Windows user management utility in VB.Net Winforms hosting PowerShell. I successfully execute the required command to set the executionpolicy for the process, the problem arises when I try and execute "Get-LocalUser" with no parameters. In the PowerShell Console on my Windows 10 Anniversary Update machine it returns the Builtin Administrator Account, Guest and my personal account. Under my application I get no objects returned from Invoke(), no errors or warnings either. What can I try to figure this issue out?
My code is:
ps.AddCommand("Get-LocalUser")
For Each user As PSObject In ps.Invoke()
MainListView.Items.Add(user.Properties("Name").ToString)
Next

How to run a Powershell Script block with elevated privileges

I am writing a PowerShell script to archive compressed C2 Audit files to a file share. What is possibly the last problem I am having is giving the .Net compression routine the privilege to manipulate the files. During development, I could flaunt my account's admin role to propagate Full Access privileges to the files in the DATA directory. However, the script is to run from a PowerShell step in an Agent job, and I want to automate the ACL change as well.
For an added level of difficulty, I am doing this under SQL Server 2012, so I am stuck with PowerShell 2.0. I am using .Net 4.5 compression routines via a process of loading $RunActivationConfigPath with a temporary config file. I was not able to find a way to change that config file to promote the admin role, though.
This is a segment of a script by Benjamin Armstrong that checks if the connection is using Administrator privileges.
# Get the ID and security principal of the current user account
$runtimeWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent();
$runtimeWindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($runtimeWindowsID);
# Get the security principal for the administrator role
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator;
Write-Output ("Running under "+$runtimeWindowsID.Name)
Write-Output ("PS Version "+$PSVersionTable.PSVersion.Major)
# Check to see if we are currently running as an administrator
if ($runtimeWindowsPrincipal.IsInRole($adminRole) -eq $true) {
Write-Output "We are strong."
} else {
Write-Output "We are not strong."
}
Running the script as an Agent Job step produces:
Running under NT Service\SQLSERVERAGENT
PS Version 2
We are not strong.
Running the script from sqlps in Admin mode produces:
Running under DOMAIN\myusername
PS Version 2
We are strong.
All the ways I've seen to elevate a script involve using a script file. For example, creating a new process and executing it with RunAs as the Verb. I want to avoid script files and have everything in the step. I like the added security (however small) of needing SSMS privileges to view the code.
So, here are my questions:
1) Is there a way to elevate commands in a script block?
2) Is there a way to have the PowerShell step in an Agent Job run in Admin mode?
Extra credit question:
3) If I do need to add the Agent service account to a Windows User Group, which of the two dozen groups would give that account the minimum privileges needed to alter an ACL for a file, then eventually delete it?

Access Denied when executing through cygwin openssh

When I execute the command "iisreset" through an ssh terminal on a remote windows machine, I get the following error:
Attempting stop...
Restart attempt failed.
Access denied, you must be an administrator of the remote computer to use this
command. Either have your account added to the administrator local group of
the remote computer or to the domain administrator global group.
When I type whoami, it shows that I am the administrator. My cygwin ssh session is running as the "cyg_server" user who has admin privileges.
My ssh server is configured with privilege separation and allows me to login as administrator.
When I run the command locally, it works fine. The problem is execution through ssh.
I've also used process monitor to see what's going on, but it does not indicate the problem.
That is pretty strange because I am able to do admin-only operations in remote ssh such as:
echo "hi">/cygdrive/c/x.txt
rm /cygdrive/c/x.txt
Turning off UAC did not make a difference.
Any ideas?
I had a similar problem: unable to start/stop services using net start/net stop from a remote password-less (public/private key) SSH user. Attempting to start/stop the service was resulting in a "System Error 5 has occurred. Access is denied." error).
I had to install Cygwin's LSA authentication package (see http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-setuid-overview) in order for (I presume) setuid to work properly for password-less logins.
The problem should go away once LSA is installed on the Cygwin/SSH host and the machine has been rebooted.
I got scared of the LSA package mentioned in #user3609241's answer because of this sentence in the LSA docs:
as soon as the LSA encounters serious problems (for instance, one of
the protected LSA processes died), it triggers a system reboot.
But, those same docs point to a very easy way to "runas" SYSTEM - just use the at command:
$ date
Mon, Jan 12, 2015 8:17:35 PM
$ at 20:18 iisreset
Added a new job with job ID = 1
$ at
Status ID Day Time Command Line
-------------------------------------------------------------------------------
1 Today 8:18 PM iisreset
It works, at the cost of having to wait up to 59 seconds.
(wrapping the above sequence of commands in a simple-to-call script is left as an exercise to the reader; our management util is written in Perl so it was pretty straightforward).
Run the Cygwin terminal as administrator

Issue with nested calls with psexec (access denied)

First of all, sorry for my poor english. I would try to explain my problem.
I am using psexec within a script to restart a cluster as follows:
script1 in node1: perform a lot of tasks (shutdown services, check status, etc..) in the node1 and after completing all task launch with psexec the script2 in node2 (psexec-d \ \ node2 script2)
script2 in node2: perform a lot of tasks and launches script3 in node1. Here is, when i recived an "access denied" in psexec when I try to run the script3 in node1. (psexec-d \ \ nodo1 script3)
I launch the script with an user that belongs to the group administrators
For security reasons I can not pass username and password, because it is not safe to leave the credentials in a .bat file.
Additional info:
I´m running the script in W2k3 server
I tried a net use and its all ok
I tried a psexec with -u username and -p username and its all ok
I tried to exec psexec with this syntax: psexec .exe -d \node1 cmd.exe "script3.bat" and returns the same error.
Thks a lot
Best Regards
Finally I have decided to use a watchdog process in the second script, so the script will be launched by this process instead of being launched by psexec.
Thanks a lot for your help and your time devoted to help me.
Best regards
It may be related with an issue that one gets from too many linked server hops using integrated authentication - a double-hop Kerberos problem.
Since Integrated Windows Authentication covers two separate authentication mechanisms:
NTLM v2 -and-
Kerberos,
if you are using Kerberos, since the user's password is never passed to the IIS server, the only way the token on the IIS server is going to hop to another machine on the network is via Kerberos Delegation. If that isn't available or allowed, then the hop won't happen (which is what it sounds like is happening).
Given that you are using default credentials, and if the current security context is an impersonation token that can not delegate, then the credentials you supply will not hop to
the other machine.
Since Windows integrated authentication creates an impersonation token, this is very likely to be the case.
Sources:
psexec problem
Windows authentification thread (forum)
Can you make the call to script2 wait for completion, rather than have script2 call back to node1:
script1 in node1: perform a lot of
tasks (shutdown services, check
status, etc..) in the node1 and after
completing all task launch with psexec
the script2 in node2 (psexec \ \ node2
script2)
script2 in node2: perform a lot of
tasks.
script1 in node1: launches script3.