Password Reset Script Setup for Delegated Control User Group - powershell

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.

Related

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

How to validate local admin credentials against a set of servers

I have 60 servers, VMs to be particular. And I have a local admin username and password. Instead of logging on to 60 servers using these local admin creds, it would be better if there is a script to check if I could log on to these servers as a local admin using the local admin creds. To be precise, I want to check.if I can use this local admin creds to successfully log on to all 60 VMs.
I have googled but no luck. I know stackoverflow is not a place to directly ask for a piece of code, but in this case I am forced to. Even if you dont have a direct answer please direct me somewhere.
gc serverlist.txt | % {
$admin_share = '\\' + $_ + '\admin$'
if (Test-Path $admin_share) {
Write-Host "Access test passed on $($_)"
} else {
Write-Host "Access test failed on $($_)"
}
}
This is a variation of your attempt.
It assumes the same username and password for all computers.
#Get list of cserver names from file
$Servers = Get-Content -Path serverlist.txt
#Prompt user foe credentials
$Cred = Get-Credential
foreach ($Svr in $Servers)
{
#path to share (\\ServerName\Admin$)
$Path = '\\' + $Svr + '\Admin$'
Try
{
#Map admin share as PS Drive (NOT visable in the GUI)
#ErrorAction stop will jump to catch block if the connection is unsuccessfull
New-PSDrive -Name TEST -PSProvider FileSystem -Root $Path -Credential $Cred -ErrorAction Stop
#Success Message
Write-Output "Connection Successful $Svr"
#Remove drive before next loop
Remove-PSDrive -Name TEST
}
Catch
{
#Error message if connection fails
Write-Warning -Message "Connect failed $Svr"
}
}
If you have ICMP enabled, you could use Test-Connection cmdlet with the Credential switch. You can see more details in example 3 here:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/test-connection?view=powershell-6

Rights needed for accessing wmi32_process.GetOwner

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?

vSphere Powercli - The specified privileges are from a different server

I have the following powercli script to add a local account to an esx host.
With all my research I believe this should work but when I run it I get this error.
New-VIRole : 3/04/2014 9:23:49 a.m. New-VIRole The specified privileges are from a different server.
At .\test.ps1:18 char:11
+ New-VIRole <<<< -Name "CIM Only" -Privilege "CIM interaction"
+ CategoryInfo : InvalidArgument: (VMware.VimAutom...ent.Privilege[]:Privilege[]) [New-VIRole], VimException
+ FullyQualifiedErrorId : Core_NewVIRole_DoWork_PrivilegeFromDifferentServerSpecified,VMware.VimAutomation.ViCore.Cmdlets.Commands.PermissionManagement.NewVIRole`
Here is the script
## As usual, load needed PowerCLI cmdlets
asnp VMware.VimAutomation.Core -ErrorAction SilentlyContinue
# Define the ESXi server
$server = "servername"
#Connect to ESXi server
Connect-VIServer -Server $server -user user -password password
#Create a new role CIM, with the only needed privilege assigned to it
New-VIRole -Name "CIM Only" -Privilege "CIM interaction"
#Create the cimuser account, assign it to root group, and deny it shell access
New-VMHostAccount -Id cimuser -Password password -UserAccount:$true -AssignGroups root -GrantShellAccess:$false
#Assign the role CIM to the newly created cimuser account
New-VIPermission -Entity $server -Principal cimuser -Role "CIM Only"
#Disconnect from ESXi server
Disconnect-VIServer -Server $server -Confirm:$false
Any help greatly appreciated.
Try this:
New-VIRole -Name "CIM Only" -Privilege ( Get-VIPrivilege "CIM interaction" )
What esxi version are you running?

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

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