I am working on a PowerShell script that (among other things) gets the currently logged in user to a list of VM's, using WMI to get the owner of any explorer.exe processes.
$User = Get-WmiObject -Class win32_process -ComputerName $strVMName -Credential $cred | `
Where-Object{ $_.Name -eq "explorer.exe" } | `
ForEach-Object{ ($_.GetOwner()).Domain + "\" + ($_.GetOwner()).User; }
This code works great, but only when the credentials used are an admin on the VM being queried. I have given a non-admin user full rights on CIMV2 in WMI Control, but the GetOwner method doesn't return anything ($user is returned as just "\") unless I add the user to the admin group as well. Since this script is intended to be run by normal users, I would rather not give them admin rights.
Can someone point me to what the minimum rights needed to use these methods? Or even a different method of getting the currently logged in user that will work for non-admins?
Related
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.
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
So I have not found anything that explains why this code will run when you open PowerShell as "Administrator", entering your domain admin credential. Whereas when you open PowerShell with no admin privilege and using the -credential Domain\DomainAdminUser, then entering your password when prompted and I get error. Why is this?
Error: Get-WinEvent: The parameter is incorrect.
I'm asking because I have a menu script which I can run it as admin using my domain admin credential but the gpresult command will not work because of "invalid pointer" and reason being is, my domain account is not part of the authenticated user.
So to make it easy, I need to run my menu script without admin rights and use the -credential switch for certain commands within the menu script.
cls
$logname = "Security"
$Id = "4634"
$Id2 = "4624"
Get-WinEvent -ComputerName $env:COMPUTERNAME -Credential Domain\DomainAdminuser #{logname=$logname;Id=$Id,$Id2;starttime=[datetime]::Today} |
Select-Object TimeCreated, Id, #{n="Message";e={($_.message).Split(" ")[0..4] -join " "}} | Format-Table -Wrap
So basically I've been working forever on a PS remote self help script that originally was thought to be simple: Restart the spooler service, clear the queue, and print a test page on the default printer. Getting there however hasn't been so easy, due to security issues. After some hours, I was able to get my local user test account to accept the credentials of my domain administrator. I thought all was well, until I tried to replicate it on a local administrator's account, in which event access was denied. This is sort of important, because the majority of the accounts we will be deploying the script on are local admins. I suspect it may be a UAC issue, but I have no idea what I should do to work around the problem. Here's what I'm working with currently:
$v = [bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544")
If ($v = "False")
{
$password = "ElPassword" | ConvertTo-SecureString -asPlainText -Force
$username = "Domainname\Username"
$credential = New-Object System.Management.Automation.PSCredential($username,$password)
invoke-command {Stop-Service spooler} -comp $env:ComputerName -cred $credential
Remove-Item C:\Windows\System32\spool\PRINTERS\* -Force
invoke-command {Start-Service spooler} -comp $env:ComputerName -cred $credential
$printer = Get-WmiObject -Query " SELECT * FROM Win32_Printer WHERE Default=$true"
$PrintTestPage = $printer.PrintTestPage() } Else
{ Stop-Service spooler
$printer = Get-WmiObject -Query " SELECT * FROM Win32_Printer WHERE Default=$true"
Start-Service spooler
$PrintTestPage = $printer.PrintTestPage() }
The first thing this does is check if the current PS session is being run as admin; seeing as the users don't actually see the PowerShell window or script, and we recently started using the RMM tool, I'm still trying to figure out under what conditions the tool runs PS elevated - the documentation says that it runs with the credentials of the logged in user, but that doesn't seem to be the case, as an hour with their support team told me that the reason the script wasn't doing it's job on any admin accounts was because it wasn't being elevated. Anyways, after the check, it either passes credentials for the commands or it doesn't. This script seems to handle every scenario but that of a local admin account running PS non elevated. In that event, it simply denies me access where the exact same creds give me access on a regular user account. I'm not sure how to even approach this problem, so any help is appreciated.
I create an OU with:
$sb = [scriptblock]::Create(
"New-ADOrganizationalUnit $cn -path `"$path`" -ProtectedFromAccidentalDeletion 0"
)
Invoke-Command -ComputerName $server -Credential $Credential `
-ScriptBlock $sb
$dn = "OU=$cn,$path"
and then try to delete it with:
$sb = [scriptblock]::Create(
"Remove-ADOrganizationalUnit `"$dn`" -Recursive -Confirm:0"
)
Invoke-Command -ComputerName $server -Credential $Credential `
-ScriptBlock $sb
And I get an "Access is denied" message
Access is denied
CategoryInfo : PermissionDenied: (...the DN...) [Remove-ADOrganizationalUnit], UnauthorizedAccessException
FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.UnauthorizedAccessException,Microsoft.ActiveDirectory.Management.Commands.RemoveADOrganizationalUnit
PSComputerName : ...my server...
Note that when created I turned off protection from accidental deletion (which I can confirm on the domain controller).
I get the same access denied message if I pass the server and credentials to
Remove-ADOrganizationalUnit -Server $server -Credential $Credential "$dn" -Recursive -Confirm:0`
and if I open a remote session and run the Remove-ADOrganizationalUnit in that context.
The really odd part is that I can point LDAP-Admin at the same server with the same credentials and delete the OU just fine. I can't explain the inconsistency.
I do see that the Effective Accesss on the newly-created object are not what I'd expect. On the OU which is the parent of the OU I create, the user has
Create/delete Group objects for this and all descendants
Create/delete Organizational Unit objects for this and all descendants
Create/delete User objects for this and all descendants
Full control for Descendant Group objects
Full control for Descendant User objects
List contents for this and all descendants
Read all properties for this and all descendants
Write all properties for this and all descendants
Read permissions for this and all descendants
But I lack Delete and Delete subtree on the OU I create. Why isn't Created/delete OU inherited and why does LDAP-Admin work and PS doesn't?
After revising the question to itemize permissions, Rubber Duck Debugging reveals that the list is inconsistent in that it lacks "Full control for Descendant Organizational Unit objects." I maintain that it shouldn't be necessary with the create/delete permissions I have and I'm baffled by the inconsistency between PS and LDAP-Admin. However, adding that Full control permission solves the problem and is an acceptable workaround for the odd inheritance or my misunderstanding of AD.