"get-wmiobject win32_process -computername" gets error "Access denied , code 0x80070005" - powershell

i'm trying to find processes on 3 terminal servers which have certain words in its $_.commandline property. Under my domain admin account, it worked OK. But I want this script to be usable for domain users, and doamin users get an error when runing this script.
What should i do, so that domain users can run this script just like domain admins? Thanks in advance!
Error:
Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESS DENIED))
At N:\FindWhoIsUsing\FindWhoIsUsing.ps1:7 char:18
get-wmiobject <<<< win32_process -computername $server -EnableAllPrivileges|
CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException
FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Powershell Code:
Write-host "Who is using this profile?"
$profile = Read-host "specify profile name"
$servers = #("server-01","server-02","server-03")
Foreach($server in $servers)
{
Write-host $server
get-wmiobject win32_process -computername $server -EnableAllPrivileges|
where{$_.name -like "*Processname*" -and
$_.CommandLine -like "*$profile*"}|
select #{n="Server";e={$server}},#{n="User";e={$_.getowner().user}},#{n="ProcessID";e= {$_.ProcessID}},{$_.CommandLine}|fl
}
Write-host "DONE Searching!"

Ok here are the steps:
Launch "wmimgmt.msc"
Right-click on "WMI Control (Local)" then select Properties
Go to the "Security" tab and select "Security" then "Advanced" then "Add"
Select the user name(s) or group(s) you want to grant access to the WMI and click ok
Grant the required permissions, I recommend starting off by granting all permissions to ensure that access is given, then remove permissions later as necessary.
Ensure the "Apply to" option is set to "This namespace and subnamespaces"
Save and exit all prompts
Add the user(s) or group(s) to the Local "Distributed COM Users" group. Note: The "Authenticated Users" and "Everyone" groups cannot be added here, so you can alternatively use the "Domain Users" group.

In my case, I was connecting from a Domain server to a Workgroup server and needed to set a registry key:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\system\LocalAccountTokenFilterPolicy=1

Related

Password Reset Script Setup for Delegated Control User Group

I am trying to delegate a user group (non-administrators) to handle password reset for an organizational unit. Since I can't install Active Directory Users and Computers on the client computer, I wrote the two following scripts:
Test.ps1:
Invoke-Command -ComputerName DC -FilePath \\DC\SharedFolder\passwordreset.ps1
passwordreset.ps1:
Function GenerateStrongPassword ([Parameter(Mandatory=$true)][int]$PasswordLength)
{
Add-Type -AssemblyName System.Web
$PassComplexCheck = $false
do {
$newPassword=[System.Web.Security.Membership]::GeneratePassword($PasswordLength,1)
If ( ($newPassword -cmatch "[A-Z\p{Lu}\s]") `
-and ($newPassword -cmatch "[a-z\p{Ll}\s]") `
-and ($newPassword -match "[\d]") `
-and ($newPassword -match "[^\w]")
)
{
$PassComplexCheck=$True
}
} While ($PassComplexCheck -eq $false)
return $newPassword
}
Import-Module ActiveDirectory
$newPassword = GenerateStrongPassword(13)
$securePassword = ConvertTo-SecureString -AsPlainText $newPassword -Force
Set-ADAccountPassword -Identity test -NewPassword $securePassword -Reset
$newPassword
It works fine on the administrator account, but it doesn't work on any user of the user group I delegate control to. It complaints about...
PS C:\Users\User1\Downloads> powershell -executionpolicy bypass -file test.ps1
[DC] Connecting to remote server DC failed with the following error message : Access is
denied. For more information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (DC:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken
I have verified that the user group has the following permission over the organizational unit:
Reset password
Read pwdLastSet
Write pwdLastSet
I also verified that the user group has read and read & execute permission on the shared folder and PowerShell script file. What other permission am I missing to get this to work for a non-administrator user account.
The main clue here is this:
[DC] Connecting to remote server DC failed with the following error message : Access is denied.
It looks like your users do not have permission to create remote PowerShell sessions on the DC. You'll need to grant them rights to execute commands on the DC.
If this is a Domain Controller you may want to consider setting up a session with a session configuration on the DC that they can import into their local session and use the ActiveDirectory cmdlets from there rather than allowing them to execute things on the DC itself. Or perhaps spin up a VM with the AD module installed that they can execute the script on. Most security personnel would frown at giving non-essential users access to execute things on your domain controller.

How to Check User's Rights via powershell on a remote or local machine

I have a script that needs to check the user' rights on the remote machine in order to confirm the user has the permissions to copy their files. When this part of the script runs, it fails 90% of the time unless the user is already an admin on the remote machine.
This is my code:
write-host Checking User Rights
#if the user provides and IP address, find the hostname
if ($sourceComputerName -match $ipPattern) {
Get-Hostname
}
else {
$global:fullHostName = $env:COMPUTERNAME
}
Write-host $sourceFolder
$permissionQuery = (Get-Acl $sourcefolder.substring(1, $sourceFolder.length - 2)).Access | Where-Object { $_.IdentityReference -match $adminusername } | Select-Object IdentityReference, FileSystemRights
if (!$permissionQuery) {
Invoke-Command -FilePath "$PSScriptRoot\LocalAdmin.ps1" -ComputerName $fullHostName -ArgumentList "$sourceRemotePath"
}
else {
write-host "Admin Rights Already Exist for $adminusername at $sourceRemotePath"
}
clear-host
Here is the Get-Hostname Function:
function global:Get-Hostname {
$queryHostname = [System.Net.DNS]::GetHostEntry($sourceComputerName) | Select-Object HostName | format-table -HideTableHeaders
$stringHostName = Out-String -InputObject $queryHostname
$splitHostName = $stringHostName.split(".", 2)
$global:fullHostName = $splitHostName[0] -replace '\s', ''
[void]$fullHostName
}
Here is the error:
[DESKTOPXXXX] Connecting to remote server DESKTOPXXXX failed with the following error message : Access is denied. For
more information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (DESKTOPXXXX:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : AccessDenied,PSSessionStateBroken
Note: I am one of the network admins and I have full admin rights on the machine I ran this script on
For effective permissions, try out Get-NTFSEffectiveAccess from the NTFSSecurity module.
The way you're currently checking permissions doesn't check for any groups that $adminusername is a member of, and may not give you accurate information.
The most common reason for "Access is denied" is that your current user is not an administrator on the remote machine, though there are other reasons listed in the Troubleshooting Guide:
Powershell remoting is not (or only partially) enabled on the remote machine.
WinRM service is not running
Remote firewall profile is in "Public network" mode (only accepts powershell remoting from the same subnet)
The current running credentials are invalid for some reason e.g. password expired.
You are double-hopping (remote from PC1 to PC2, then remote again to PC3)
First, try manually providing credentials:
$cred = Get-Credential -UserName Domain\AdminUser -Message Remote
Invoke-Command -Computername $sourceComputerName -Credential $cred -ScriptBlock {Hostname}
If you still get errors, try re-running the remote powershell setup on the remote machine (and restart it):
Enable-PSRemoting -Force

find service account on remote hosts

Could you please advise how to find all servers where a specific service account is being used to start Windows services?
I am trying this in PowerShell with these code:
Clear-Host
$address = Get-Content '.\asg connections.csv'
$serviceName = "startname='NT AUTHORITY\\LocalService'"
gwmi Win32_Service -Filter $serviceName -Computer $address
Above piece of code works for "localhost", but gives below error for the remote hosts:
gwmi : Access is denied. (Exception from HRESULT: 0x80070005
(E_ACCESSDENIED))
At F:\Temp\powershell\play.ps1:30 char:1
+ gwmi win32_service -filter $serviceName -computer $address
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
When you use PowerShell remoting you implicitly trying to use the credentials your current Windows session is logged into your machine with on the target machines.
It looks like you do not have any rights with your current set of credentials on those machines.
Are the target machines joined into the same domain as your current user credentials?
If you have a set of working credentials you can log onto those machines with, you can add it in your command with:
Clear-Host
#Promts you for the username and password you wish to save to a credential object
$Cred = Get-Credential
$address = Get-Content '.\asg connections.csv'
$serviceName = "startname='NT AUTHORITY\\LocalService'"
gwmi Win32_Service -Filter $serviceName -Computer $address -Credential $Cred
If the script needs to run automated there are a few different ways to save credential passwords either into an encrypted textfile that can only be decrypted by the user account that encrypted it, or using the build in Windows Credential Vault.

What are the permissions required for CIMSessions

I need to query some WMI classes on Servers that I do not have permissions.
Here is the error I get when I run it.
PS> get-ciminstance -ComputerName test.mydomain.com -ClassName Win32_OperatingSystem
get-ciminstance : Access is denied.
At line:1 char:1
+ get-ciminstance -ComputerName test.mydomain.com -ClassName Win32_Operating ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (root\cimv2:Win32_OperatingSystem:String) [Get-CimInstance], CimException
+ FullyQualifiedErrorId : HRESULT 0x80070005,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand
+ PSComputerName : test.mydomain.com
Right now server has PowerShell 2, so it uses DCOM but I will get the PowerShell upgraded and configured to allow WSMAN connections.
But what are the permissions that need to be granted to the account?
By default, Administrators (local) and Authenticated Users (domain) have at least read rights to the namespace. You need to ensure you can login/authenticate to the server. It's worth mentioning that the Authenticated Users group does not have Remote Enable permission by default.
The Windows OS uses WinRM for CIM cmdlets and the user account needs to be an administrator. WinRM makes a local group called WinRMRemoteWMIUsers_ and gives access to just the Administrators group and WinRMRemoteWMIUsers_. To add a user to that group use the following command:
net localgroup WinRMRemoteWMIUsers__ /add "domain\user"
The abstract answer is simply that you need to be granted Enable Account and Remote Enable permissions to the Namespace to have WMI read rights remotely.
Process to Verify WMI Permissions
Login to the server and launch mmc.exe. Add the WMI snapin and once it loads, right click on WMI Control. When the Properties window opens, click security, expand root and select cimv2. Click the security button and view who is granted access and what access is granted.
Script to Test w/ DCOM
If you want to test using DCOM, or need to because the server OS is too old, use this script:
$Computer = thisbox.domain.com
$CimOption = New-CimSessionOption -Protocol Dcom
$CimSession = New-CimSession -ComputerName $Computer -SessionOption $CimOption
Get-CimInstance -ClassName win32_operatingsystem -CimSession $CimSession

Get-WmiObject credentials not working when scheduled

I have a Powershell script to detect disk space on a network server that requires a user/password to access it.
I followed this: http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/440ab7ed-7727-4ff7-a34a-6e69e2dff251/
To get this code:
$password = get-content C:\creds.txt | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "username",$password
Get-WmiObject -ErrorAction Stop Win32_LogicalDisk -ComputerName $deviceName -credential $cred -Filter "DeviceID='$darg'"
$deviceName and $darg are already correctly defined.
This works just fine when running the Powershell script manually. But when I set it up as a Windows schedule task, it fails thinking the user/pass is incorrect:
Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESS
DENIED))
$disks = Get-WmiObject <<<< -ErrorAction Stop Win32_LogicalDisk -ComputerName $deviceName -credential $cred -Filter
"DeviceID='$darg'"
+ CategoryInfo : NotSpecified: (:) [Get-WmiObject], Unauthorized AccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Why is this? (The account is a local user on the remote server. I've tried entering the credentials on the Schedule interface but it doesn't let me save it, saying invalid login; maybe due to being a local account) ServerName\LocalUser does not work in the Windows Schedule UI, still gives the incorrect login error.
Here is my comment, re-worded as an answer.
The convertto/from-securestring functions work on a per-user basis (if you don't provide a specific key value). IOW, one user can't read another user's data.
This pre-existing SO question seems relevant. There is also relevant discussion at Powershellcommunity.org.
why dont you set the task to run under the user account and run the wmi request without credential ?