Get admin groups with powershell - powershell

I work as system administrator in a company with 300 users.
I am looking for a PowerShell script to get all the groups, users in each group and additional single users located at the local admin group of multiple servers joined to a single domain.
This is what I have but it's for local users only.
# Get local and Groups Users List with Content
function get-localusers {
param(
[Parameter(Mandatory=$true,valuefrompipeline=$true)]
[string]$strComputer)
begin {}
Process {
$Select = "Name","Class" | %{
Invoke-Expression "#{n='$_';e={ `$_.GetType().InvokeMember('$_', 'GetProperty', `$Null, `$_, `$Null) }}"
}
If (Test-Connection $strComputer -Count 2 -Quiet){
$computer = [ADSI]("WinNT://" + $strComputer + ",computer")
$Users = $computer.psbase.children | ? {$_.psbase.SchemaClassName -eq "User"}
foreach ($User in $Users) {
$User | Select #{N="ComputerName";E={$strComputer}},#{N="User";E={$_.Name}},Class
}
}
Else {
"" | Select #{N="ComputerName";E={$strComputer}},#{N="User";E={"Not able to Ping"}},Class
}
}
end {}
}
Get-Content "c:\temp\Servers.txt" | get-localusers | Select ComputerName,User | Export-Csv "c:\temp\Local-User_$((get-date).toString('MM-dd-yyyy')).csv" -NTI
This is the output from the script above.
"ComputerName", "User"
"mbptl-ws01","mbadmin"
"mbptl-ws01","Guest"
"mbptl-ws01","sv-dtb-pr"
Please help aggregating by groups ( that show users)

Seems that this is a good start :
https://4sysops.com/archives/create-a-list-of-local-administrators-with-powershell/
looks that this will at least get you the members for several computers

Related

output all mailboxes with inbox rules

I am trying to get a list of all Exchange mailboxes that have inbox rules. I am able to get a list of all mailboxes and a count of how many rules each mailbox has. I am trying to skip or have no output for mailboxes with zero rules.
$mailboxes = get-mailbox
foreach ($mailbox in $mailboxes) {
Write-Output $mailbox.id,((Get-InboxRule -Mailbox $mailbox.id)| Measure-Object | select count)
}
Current code outputs:
User1
0
User2
11
User3
0
User4
1
User5
0
etc....
I am looking to only output user's who have inbox rules.
Thanks-
#!/usr/bin/env powershell
get-mailbox -resultsize unlimited |
ForEach-Object {
Write-Output -Message ('Checking {0}...' -f $_.alias) -Verbose
$inboxrule = get-inboxrule -Mailbox $_.alias
if ($inboxrule) {
foreach($rule in $inboxrule){
New-Object -TypeName PSObject -Property #{
Mailbox = $_.alias
## you could uncomment this if you wanted more information
##Rulename = $rule.name
##Rulepriority = $rule.priority
##Ruledescription = $rule.description
}
}
}
} |
Export-csv -Path "$env:userprofile/desktop/export.csv" -NoTypeInformation
This should give you a list of just the users who have rules.
Not exactly sure what your expected is but to answer how to exclude those mailboxes with no inbox rules:
foreach($mailbox in Get-Mailbox) {
$ibxrules = #(Get-InboxRule $mailbox.Id).Count
if($ibxrules -eq 0) {
continue
}
[pscustomobject]#{
MailboxId = $mailbox.Id
InboxRules = $ibxrules
}
}
To explain the use of #(...) around Get-InboxRule, this is to ensure the output is always an array, and this also ensures we can always get a .Count out of it.

Get-ADGroupMember processing for non domain members

We have a trusted domain that we administer and users are given acceess to a file server on our domain through groups on the trusted domain added to the local domain group which controls permissions e.g.
For the path "\server\folder\folder" the permissions might look like
MyDomain\FolderXReadWrite
Then within that group a group from the trusted domain would be included
TrustedDomain\FolderXReadWrite
I'd like to write a script to "reverse engineer" this so that I can derive both the local and trusted domain groups that have access from a given folder path and list them - I've got the following:
$path = '\\server\path\path'
$Permissions = (Get-Item -Path $path -ErrorAction Stop | Get-Acl -ErrorAction Stop).Access | Where-Object { $_.IdentityReference -like "MyDomain\*" } | ForEach-Object {
$TrustedDomGroup = Get-ADGroupMember ($_.IdentityReference.Value -split '\\')[1] -Verbose | Where-Object { ($_.DistinguishedName -split 'DC=', 2)[-1] -like "*TrustedDomain*" -and ($_.objectClass -eq 'group') }
If ($TrustedDomGroup) {
[pscustomobject]#{Name=("TrustedDomain\" + $TrustedDomGroup.SamAccountName);Rights=("Member of " + $_.IdentityReference);Domain='PHS'}
}
[pscustomobject]#{Name=$_.IdentityReference;Rights=$_.FileSystemRights;Domain='NSS'}
}
$Permissions | Sort-Object Name -Unique
This produces the output I require, however, the domain group in the above example has LOTS of users therefore processing "Get-ADGroupMember" takes a long time. Does anyone have suggestions for a faster method?
you can try to retrieve all group members with this command:
(Get-ADGroup $ADGroup -Properties members).members
I don't know if it's faster in your environment then Get-AdGroupMember.
A measurement via Measure-Command may give you more information:
Measure-Command, Microsoft Docs
Ok, so the best method to improve the lookup speed seems to be using LDAP so I put together a small function to get Foreign Security Principal group names from a local AD group:
Function List-FSPGroupMembers {
# Use LDAP search to find and resolve Foreign Security Principals from an AD group - faster than native cmdlet
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true,Position=1)][string]$GroupName="",
[Parameter(Mandatory=$true,Position=2)][string]$Domain
)
[regex]$SIDmatch = "S-\d-(?:\d+-){1,14}\d+"
Function fGetADGroupObjectFromName([System.String]$sGroupName,[System.String]$sLDAPSearchRoot) {
$oADRoot = New-Object System.DirectoryServices.DirectoryEntry($sLDAPSearchRoot)
$sSearchStr ="(&(objectCategory=group)(name="+$sGroupName+"))"
$oSearch=New-Object directoryservices.DirectorySearcher($oADRoot,$sSearchStr)
$oFindResult=$oSearch.FindAll()
If($oFindResult.Count -eq 1) {
Return($oFindResult)
}
Else{
Return($false)
}
}
$sSearchRoot="LDAP://" + $Domain + ":3268"
If($oSearchResult=fGetADGroupObjectFromName $groupname $sSearchRoot) {
$oGroup=New-Object System.DirectoryServices.DirectoryEntry($oSearchResult.Path)
$oGroup.Member | Where-Object {($_.ToString()) -match $SIDmatch } | ForEach-Object {
$SID = (Select-String -Pattern $SIDmatch -InputObject $_.ToString()).Matches.Value
Try {
(New-Object System.Security.Principal.SecurityIdentifier($SID)).Translate([System.Security.Principal.NTAccount]).Value
}
Catch {
$_
}
}
}
Else {
Write-Warning ("Group "+$groupname+" not found at "+$domain)
}
}

Issue with ADSI script not pulling users from all groups

I have a list of groups that i need to pull back all users. I am aware due to the numbers it is restricted. I have tried adding page size but it does not work.
Here is the code
Get-Module ActiveDirectory - ErrorAction silentlycontinue
Function resolve-group}
param ($group)
For each ($member in $group.member){
$obj = [ADSI] ("LDAP://" + member)
if (obj.objectclass[1] -eq 'group'){resolve-group $obj}
else {
If ($obj.employeeid.length -eq 6)
{
$displayname = $obj.displayname
$employeeid = $obj.employeeid
$groupname = $group.name
$global:members +="$employeeid,$displayname,$groupname"
}
}
}
}
$global:members =#()
$group = [ADSI] "LDAP://cn=ab,ou=cd,ou=ef,DC=gh,DC=BB"
resolve-group $group
$group = [ADSI] "LDAP://cn=aa,ou=cc,ou=ef,DC=gh,DC=BB"
resolve-group $group
"ID,Name,Group" > c:\test\groups.csv
$global:members | sort-object - unique >> c:\test\groups.csv
I don't know how to amend the script to add and increase the page size?
I have only listed a couple of the groups but there are 100's of groups
Thanks

Create a PowerShell script that would get the last 30 days history logon of Domain Admin member

I would like to write a Power Shell script that would do the following:
- If the user is member of (Domain admins) get me the last 30 days history logon of this user in any Domain joined computer.
I created something now but it still lacks a lot as it reads the security events on the Domain controller and brings the users,time and matches them with the Domain admin group as in the attached screenshot
I would appreciate if someone can help me evolve this script into something useful
$Rusers = Get-WinEvent -Computer dc02 -FilterHashtable #{Logname='Security';ID=4672} -MaxEvents 50 |
` select #{N='User';E={$_.Properties[1].Value}},TimeCreated
$DAUsers = Get-ADGroupMember -Identity "Domain Admins"
Foreach ($DAUser in $DAUsers){
$DomainUser = $DAUser.SamAccountName
foreach ($Ruser in $Rusers){
$RAUser = $Ruser.User
If ($RAUser -match $DomainUser){
Write-Host $Ruser is domain admin }
}[![enter image description here][1]][1]
}
# Get domain admin user list
$DomainAdminList = Get-ADGroupMember -Identity 'Domain Admins'
# Get all Domain Controller names
$DomainControllers = Get-ADDomainController -Filter * | Sort-Object HostName
# EventID
$EventID = '4672'
#
# Get only last 24hrs
$Date = (Get-Date).AddDays(-1)
# Limit log event search for testing as this will take a LONG time on most domains
# For normal running, this will have to be set to zero
$MaxEvent = 50
# Loop through Dcs
$DALogEvents = $DomainControllers | ForEach-Object {
$CurDC = $_.HostName
Write-Host "`nSearching $CurDC logs..."
Get-WinEvent -Computer $CurDC -FilterHashtable #{Logname='Security';ID=$EventID;StartTime = $Date} -MaxEvents $MaxEvent |`
Where-Object { $_.Properties[1].Value -in $DomainAdminList.SamAccountName } |`
ForEach-Object {
[pscustomobject]#{SamAccountName = $_.Properties[1].Value;Time = $_.TimeCreated;LogonEventLocation = $CurDC}
}
}
All the Domain Admin logon events should now be in $DALogEvents
You'll need to group results by name, then export to a file
Thanks a lot for your help, I apologize I was not clear enough. The kind of information I am looking for is pertaining to users who have been utilized for services e.g. (SQL reporting Services, Or Sccm Service ..etc )
This script does what I want but it doesn't run only for domain admin users, it runs for everyone basically and not sure if there's a limit to the time/date.
Is it possible to adjust it to let it run against Domain Admin users for 30 days and print information like. Source IP, User, Target Dc, Date?
Get-EventLog -LogName Security -InstanceId 4624 |
ForEach-Object {
# translate the raw data into a new object
[PSCustomObject]#{
Time = $_.TimeGenerated
User = "{0}\{1}" -f $_.ReplacementStrings[5], $_.ReplacementStrings[6]
Type = $_.ReplacementStrings[10]
"Source Network Address" = $_.ReplacementStrings[18]
Target = $_.ReplacementStrings[19]
}
}
I've added couple more of custom objects to get the result that I needed. I think turning this into a function would be great tool to use for auditing.
Thanks a lot to you #Specialist
# Get domain admin user list
$DomainAdminList = Get-ADGroupMember -Identity 'Domain Admins'
# Get all Domain Controller names
$DomainControllers = Get-ADDomainController -Filter * | Sort-Object HostName
# EventID
$EventID = '4624'
#
# Get only last 24hrs
$Date = (Get-Date).AddDays(-3)
# Limit log event search for testing as this will take a LONG time on most domains
# For normal running, this will have to be set to zero
$MaxEvent = 100
# Loop through Dcs
$DALogEvents = $DomainControllers | ForEach-Object {
$CurDC = $_.HostName
Write-Host "`nSearching $CurDC logs..."
Get-WinEvent -ComputerName $CurDC -FilterHashtable #{Logname='Security';ID=$EventID;StartTime = $Date} -MaxEvents $MaxEvent |`
Where-Object { $_.Properties[5].Value -in $DomainAdminList.SamAccountName } |`
ForEach-Object {
[pscustomobject]#{SourceIP = $_.Properties[18].Value; SamAccountName = $_.Properties[5].Value;Time = $_.TimeCreated;LogonEventLocation = $CurDC}
}
}
$DALogEvents

How do you export a list of PC names and a specific group membership of that endpoint using powershell?

I have a list of end points and we are trying to see if they have this specific group membership but I cannot figure out how to export the endpoint and the group its a member of.
$Groups = foreach ($pc in (Get-Content "C:\Users\*\Desktop\DefualtTest.csv")) {
try {
Get-ADComputer $pc -Properties memberof |
select -Expand memberof |
dsget group -samid |
? {$_ -match 'bit9'}
} catch {
Write-Output "$pc does not have bit9 group"
}
}
$Groups | Out-File "C:\Users\*\Desktop\testONE.csv"
trying to do this in comments is ... to difficult. [grin]
here's an example of what i mean by "do it one line at a time" in the foreach loop ...
# fake reading a list of systems from a text file
# in real life, use Get-Content
$ComputerList = #'
pc01
pc02
pc03
pc04
pc05
pc666
'# -split [environment]::NewLine
# fake getting a list of Computers & the groups they are in
# in real life, use Get-ADComputer & the ".MemberOf" property
$GroupMembershipLookup = #{
'pc01' = #('GroupA', 'GroupB')
'pc02' = #('GroupB', 'GroupC', 'GroupD')
'pc03' = #('GroupA', 'GroupB', 'GroupE')
'pc04' = #('GroupZ')
}
$NoGroupFound = '__No Group Found__'
$Results = foreach ($CL_Item in $ComputerList)
{
# use a real call to Get-ADComputer here [*grin*]
# pro'ly something like "(Get-ADComputer $CL_Item -Property MemberOf).MemberOf -join '; '"
$GroupList = $GroupMembershipLookup[$CL_Item] -join '; '
if ([string]::IsNullOrEmpty($GroupList))
{
$GroupList = $NoGroupFound
}
[PSCustomObject]#{
ComputerName = $CL_Item
GroupMembership = $GroupList
}
}
# on screen
$Results
# to CSV
$Results |
Export-Csv -LiteralPath "$env:TEMP\Del_GroupMembershipList.csv" -NoTypeInformation
on screen output ...
ComputerName GroupMembership
------------ ---------------
pc01 GroupA; GroupB
pc02 GroupB; GroupC; GroupD
pc03 GroupA; GroupB; GroupE
pc04 GroupZ
pc05 __No Group Found__
pc666 __No Group Found__
csv content ...
"ComputerName","GroupMembership"
"pc01","GroupA; GroupB"
"pc02","GroupB; GroupC; GroupD"
"pc03","GroupA; GroupB; GroupE"
"pc04","GroupZ"
"pc05","__No Group Found__"
"pc666","__No Group Found__"
what the above does ...
creates an array of system names as if they had been read in via Get-Content
creates a lookup table as if one had used Get-ADComputer to get the group membership for each system
made a "not found" value & stored that in a $Var for reuse
iterated thru the $ComputerList collection
grabbed the list/array of groups and converted them into a semicolon delimited string
tested for "no groups found" & added the value saved earlier if the list was empty
built a [PSCustoObject] and sent that to the output stream
captured the output stream to an array named $Results all at one time to avoid the += array penalty
displayed the results on screen
sent the $Results collection to a CSV file