Skip to content

Instantly share code, notes, and snippets.

@frndlyy
Last active January 5, 2024 15:49
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save frndlyy/e7e51d3acddee51c4e42d0ee9bbe0dc0 to your computer and use it in GitHub Desktop.
PowerShell Scripts and Snippets/One Liners
#This script will display the ADPrep Version for your Schema, Forest, Domain and RODC
Import-Module ActiveDirectory
CD AD:
$Forest = Read-Host 'Put your forest name in DN format like DC=msft,DC=Net'
$Rootdomain=Get-ADForest | select RootDomain
$Schemaversion=[ADSI]"LDAP://cn=schema,cn=configuration,$Forest"
$ForsetPrep=[ADSI]"LDAP://CN=ActiveDirectoryUpdate,CN=ForestUpdates,cn=configuration,$Forest"
$RODCPrep=[ADSI]"LDAP://CN=ActiveDirectoryRodcUpdate,CN=ForestUpdates,cn=configuration,$Forest"
$domainPrep=[ADSI]"LDAP://CN=ActiveDirectoryUpdate,CN=DomainUpdates,CN=System,$Forest"
Write-Host "Schema Version"
$Schemaversion.Properties.objectVersion
Write-Host "ForestPrep Version"
$ForsetPrep.Properties.revision
Write-Host "RODCPrep Version"
$RODCPrep.Properties.revision
Write-Host "DomainPrep Version"
$domainPrep.Properties.revision
sl c:
#The command get-adgroup has a resultset limit which we can override using ResultSetSize and ResultPageSize
#Remove Members from a Group. Don't prompt for confirmation
Get-ADGroupMember "TestGroup" | ForEach-Object {Remove-ADGroupMember "TestGroup" $_ -Confirm:$false}
#Remove members from all groups in an OU. Don't prompt for confirmation
$ALLGroups=Get-ADGroup -Filter * -SearchBase "OU=Neptune,OU=Distribution Lists,DC=PowerShellJunkie,DC=com" -ResultPageSize 1000 -ResultSetSize $null
ForEach($Group in $ALLGroups)
{
Get-ADGroupMember "$Group" | ForEach-Object {Remove-ADGroupMember "$Group" $_ -Confirm:$false}
}
#This command doesn't have a limit and it's way faster
Get-ADGroup | Set-ADObject -Clear members
<#-----------------------------------------------------------------------------
Group report & Search for groups with duplicate group membership
Ashley McGlone - GoateePFE
Microsoft Premier Field Engineer
http://aka.ms/GoateePFE
January, 2014
-------------------------------------------------------------------------------
LEGAL DISCLAIMER
This Sample Code is provided for the purpose of illustration only and is not
intended to be used in a production environment. THIS SAMPLE CODE AND ANY
RELATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. We grant You a
nonexclusive, royalty-free right to use and modify the Sample Code and to
reproduce and distribute the object code form of the Sample Code, provided
that You agree: (i) to not use Our name, logo, or trademarks to market Your
software product in which the Sample Code is embedded; (ii) to include a valid
copyright notice on Your software product in which the Sample Code is embedded;
and (iii) to indemnify, hold harmless, and defend Us and Our suppliers from and
against any claims or lawsuits, including attorneys’ fees, that arise or result
from the use or distribution of the Sample Code.
-------------------------------------------------------------------------------
This script compares group memberships for the entire domain to find
duplication. This involves an "n * n-1" number of comparisons. The following
steps have been taken to make the comparisons more efficient:
- Minimum number of members in a group before it is considered for matching
This automatically filters out empty groups and those with only a few members.
This is an arbitrary number. Default is 5. Must be at least 1.
- Minimum percentage of overlap between group membership counts to compare
ie. It only makes sense to compare groups whose total membership are close
in number. You wouldn't compare a group with 5 members to a group with 65
members when seeking a high number of group member duplicates. By default
the lowest group count must be within 25% of the highest group count.
- Does not compare the group to itself.
- The pair of groups has not already been compared.
Groups of all types are compared against each other in order to give a complete
picture of group duplication (Domain Local, Global, Universal, Security,
Distribution). If desired, mismatched group category and scope can be filtered
out in Excel when viewing the CSV file output.
Using the data from this report you can then go investigate groups for
consolidation based on high match percentages.
-------------------------------------------------------------------------------
The group list report gives you handy fields for analyzing your groups for
cleanup: whenCreated, whenChanged, MemberCount, MemberOfCount, SID,
SIDHistory, DaysSinceChange, etc. Use these columns to filter or pivot in
Excel for rich reports. For example:
- Groups with zero members
- Groups unchanged in 1 year
- Groups with SID history to cleanup
- Etc.
-------------------------------------------------------------------------sdg-#>
Import-Module ActiveDirectory
#region########################################################################
# Tuning parameters for group member matching
# Due to the number of possible group comparisons the execution time could be
# significant. These two threshold values will speed up the process by weeding
# out unlikely matches.
# Minimum number of members in a group before it is considered for matching
# This automatically filters out empty groups and those with only a few members.
# This is an arbitrary number. Must be at least 1.
$MinMember = 5
# Minimum percentage of overlap between group membership counts to compare
# ie. It only makes sense to compare groups whose total membership are close in
# number. You wouldn't compare a group with 5 members to a group with 65 members
# when seeking a high number of group member duplicates. This is an arbitrary
# number.
$CountPercentThreshold = 75
#endregion#####################################################################
# Initialize arrays and hashtables
$report = @()
$done = @{}
#region########################################################################
# List of all groups and the count of their member/memberOf
# You could edit this query to limit the scope and filter by:
# - group name pattern
# -Filter {name -like "*foo*"}
# - group scope
# -Filter {GroupScope -eq 'Global'}
# - group category
# -Filter {GroupCategory -eq 'Security'}
# - OU path
# -SearchBase 'OU=Groups,OU=NA,DC=contoso,DC=com' -SearchScope SubTree
# - target GC port 3268 and query for only Universal groups to compare
# -Server DC1.contoso.com:3268 -Filter {GroupScope -eq "Universal"}
# - etc.
Write-Progress -Activity "Getting group list..." -Status "..."
$GroupList = Get-ADGroup -Filter * -Properties Name, DistinguishedName, `
GroupCategory, GroupScope, whenCreated, whenChanged, member, `
memberOf, sIDHistory, SamAccountName, Description |
Select-Object Name, DistinguishedName, GroupCategory, GroupScope, `
whenCreated, whenChanged, member, memberOf, SID, SamAccountName, `
Description, `
@{name='MemberCount';expression={$_.member.count}}, `
@{name='MemberOfCount';expression={$_.memberOf.count}}, `
@{name='SIDHistory';expression={$_.sIDHistory -join ','}}, `
@{name='DaysSinceChange';expression=`
{[math]::Round((New-TimeSpan $_.whenChanged).TotalDays,0)}} |
Sort-Object Name
$GroupList |
Select-Object Name, SamAccountName, Description, DistinguishedName, `
GroupCategory, GroupScope, whenCreated, whenChanged, DaysSinceChange, `
MemberCount, MemberOfCount, SID, SIDHistory |
Export-CSV .\GroupList.csv -NoTypeInformation
#endregion#####################################################################
#region########################################################################
# Outer loop of all groups
# Minimize expensive group comparison operations:
# - There are more than x members in the group
ForEach ($GroupA in ($GroupList | `
Where-Object {$_.MemberCount -ge $MinMember})) {
$CountA = $GroupA.MemberCount
# Inner loop of all groups
# Minimize expensive group comparison operations:
# - Group SIDs are not equal
# - There are more than x members in the group
ForEach ($GroupB in ($GroupList | Where-Object `
{$_.MemberCount -ge $MinMember -and $_.SID -ne $GroupA.SID})) {
$CountB = $GroupB.MemberCount
Write-Progress `
-Activity "Comparing members of $($GroupA.Name)" `
-Status "To members of $($GroupB.Name)"
# Calculate the percentage of overlap between group membership counts
If ($CountA -le $CountB) {
$CountPercent = $CountA / $CountB * 100
} Else {
$CountPercent = $CountB / $CountA * 100
}
# Minimize expensive group comparison operations:
# - The pair of groups has not already been compared
# - The difference in total group count is not more than x%
If ( (!$done.ContainsKey("$($GroupA.SID)~$($GroupB.SID)")) -and `
$CountPercent -ge $CountPercentThreshold ) {
# This is the heart of the script. Compare group memberships.
$co = Compare-Object -IncludeEqual `
-ReferenceObject $GroupA.Member `
-DifferenceObject $GroupB.Member
$CountEqual = ($co | Where-Object {$_.SideIndicator -eq '=='} | `
Measure-Object).Count
# Add an entry for GroupA/GroupB
$report += New-Object -TypeName PSCustomObject -Property @{
NameA = $GroupA.Name
NameB = $GroupB.Name
CountA = $CountA
CountB = $CountB
CountEqual = $CountEqual
MatchPercentA = [math]::Round($CountEqual / $CountA * 100,2)
MatchPercentB = [math]::Round($CountEqual / $CountB * 100,2)
ScopeA = $GroupA.GroupScope
ScopeB = $GroupB.GroupScope
CategoryA = $GroupA.GroupCategory
CategoryB = $GroupB.GroupCategory
DNA = $GroupA.DistinguishedName
DNB = $GroupB.DistinguishedName
}
# Add an entry for GroupB/GroupA
# We don't need to process each pair twice,
# but we will report on each one as A/B and B/A for ease of use.
$report += New-Object -TypeName PSCustomObject -Property @{
NameA = $GroupB.Name
NameB = $GroupA.Name
CountA = $CountB
CountB = $CountA
CountEqual = $CountEqual
MatchPercentA = [math]::Round($CountEqual / $CountB * 100,2)
MatchPercentB = [math]::Round($CountEqual / $CountA * 100,2)
ScopeA = $GroupB.GroupScope
ScopeB = $GroupA.GroupScope
CategoryA = $GroupB.GroupCategory
CategoryB = $GroupA.GroupCategory
DNA = $GroupB.DistinguishedName
DNB = $GroupA.DistinguishedName
}
# Use a hashtable for quick lookup to see if the
# pair has already been processed. In this case
# we add the pair both ways to register
# completion.
$done.Add("$($GroupA.SID)~$($GroupB.SID)",1)
$done.Add("$($GroupB.SID)~$($GroupA.SID)",1)
}
}
}
$report |
Sort-Object CountEqual -Descending |
Select-Object NameA, NameB, CountA, CountB, CountEqual, MatchPercentA, `
MatchPercentB, ScopeA, ScopeB, CategoryA, CategoryB, DNA, DNB |
Export-CSV .\GroupMembershipComparison.csv -NoTypeInformation
#endregion#####################################################################
Get-ChildItem .\*.csv
$SGPath = "OU=Security Groups,OU=Starks,OU=Castle Black,DC=Winterfell,DC=com"
$SG = Import-Csv C:\Temp\SG.csv -Header @("Name","DisplayName","Description")
foreach ($line in $SG)
{
Write-Host $line
New-ADGroup -Name $line.name -DisplayName $line.DisplayName -Description $line.Description -GroupCategory Security -GroupScope Universal -Path $SGPath
}
Import-Module ActiveDirectory
Get-ADObject -LDAPFilter "(objectCategory=msExchDynamicDistributionList)" -Properties * | Select-Object {$_.Name},{$_.mail},{$_.DisplayName},{$_.msExchDynamicDLFilter},{$_.msExchQueryFilter},{$_.proxyAddresses} | Export-Csv c:\temp\Query_Based_groups.CSv -Append -NoTypeInformation
#This script is basically going through a group's members and if the member is a group, then it will go through that group's members and continue until it doesn't find any nested groups
function Get-ADNestedGroupMembers {
[cmdletbinding()]
param (
[String] $GroupName
)
import-module activedirectory
$Members = Get-ADGroupMember -Identity $GroupName
$members | % {
if($_.ObjectClass -eq "group") {
Get-ADNestedGroupMembers -GroupName $_.distinguishedName
} else {
return $_.distinguishedname
}
}
}
Get-ADNestedGroupMembers -GroupName "Khaleesi_Friends"
#Test code for future
#(Get-ADGroup -Filter {Name -eq $GroupName} -Properties Members -ResultPageSize 100 -ResultSetSize $null | Select Members).Members
Function Get-ADGroupMemberDate {
<#
.SYNOPSIS
Provides the date that a member was added to a specified Active Directory group.
.DESCRIPTION
Provides the date that a member was added to a specified Active Directory group.
.PARAMETER Group
The group that will be inspected for members and date added. If a distinguished name (dn) is not used,
an attempt to get the dn before making the query.
.PARAMETER DomainController
Name of the domain controller to query. Optional parameter.
.NOTES
Name: Get-ADGroupMemberDate
Author: Boe Prox
DateCreated: 17 May 2013
Version 1.0
The State property will be one of the following:
PRESENT: User currently exists in group and the replicated using Linked Value Replication (LVR).
ABSENT: User has been removed from group and has not been garbage collected based on Tombstone Lifetime (TSL).
LEGACY: User currently exists as a member of the group but has no replication data via LVR.
.EXAMPLE
Get-ADGroupMemberDate -Group "Domain Admins" -DomainController DC3
ModifiedCount : 2
DomainController : DC3
LastModified : 5/4/2013 6:48:06 PM
Username : joesmith
State : ABSENT
Group : CN=Domain Admins,CN=Users,DC=Domain,DC=Com
ModifiedCount : 1
DomainController : DC3
LastModified : 1/6/2010 7:36:08 AM
Username : adminuser
State : PRESENT
Group : CN=Domain Admins,CN=Users,DC=Domain,DC=Com
...
Description
-----------
This lists out all of the members of Domain Admins using DC3 as the Domain Controller.
.EXAMPLE
Get-ADGroup -Identity "TestGroup" | Get-ADGroupMemberDate
ModifiedCount : 2
DomainController : DC1
LastModified : 5/4/2013 6:48:06 PM
Username : joesmith
State : ABSENT
Group : CN=TestGroup,OU=Groups,DC=Domain,DC=Com
ModifiedCount : 1
DomainController : DC1
LastModified : 1/6/2010 7:36:08 AM
Username : bobsmith
State : PRESENT
Group : CN=TestGroup,OU=Groups,DC=Domain,DC=Com
...
Description
-----------
This lists out all of the members of TestGroup from the output of Get-ADGroup and auto-selecting DC1 as the Domain Controller.
#>
[OutputType('ActiveDirectory.Group.Info')]
[cmdletbinding()]
Param (
[parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True,Mandatory=$True)]
[Alias('DistinguishedName')]
[string]$Group,
[parameter()]
[string]$DomainController = ($env:LOGONSERVER -replace "\\\\")
)
Begin {
#RegEx pattern for output
[regex]$pattern = '^(?<State>\w+)\s+member(?:\s(?<DateTime>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})\s+(?:.*\\)?(?<DC>\w+|(?:(?:\w{8}-(?:\w{4}-){3}\w{12})))\s+(?:\d+)\s+(?:\d+)\s+(?<Modified>\d+))?'
}
Process {
If ($Group -notmatch "^CN=.*") {
Write-Verbose "Attempting to get distinguished name of $Group"
Try {
$distinguishedName = ([adsisearcher]"name=$group").Findone().Properties['distinguishedname'][0]
If (-Not $distinguishedName) {Throw "Fail!"}
} Catch {
Write-Warning "Unable to locate $group"
Break
}
} Else {$distinguishedName = $Group}
Write-Verbose "Distinguished Name is $distinguishedName"
$data = (repadmin /showobjmeta $DomainController $distinguishedName | Select-String "^\w+\s+member" -Context 2)
ForEach ($rep in $data) {
If ($rep.line -match $pattern) {
$object = New-Object PSObject -Property @{
Username = [regex]::Matches($rep.context.postcontext,"CN=(?<Username>.*?),.*") | ForEach {$_.Groups['Username'].Value}
LastModified = If ($matches.DateTime) {[datetime]$matches.DateTime} Else {$Null}
DomainController = $matches.dc
Group = $distinguishedName
State = $matches.state
ModifiedCount = $matches.modified
}
$object.pstypenames.insert(0,'ActiveDirectory.Group.Info')
$object
}
}
}
}
#<Requires Quest Active Directory Management Tools v2.0 or higher>
Add-PSSnapin Quest.ActiveRoles.ADManagement
Function Get-GroupMemberTree {
Param(
$Identity,
$IndentLevel = 0,
$IndentCharacter = "`t"
)
Write-Host "$($IndentCharacter * $IndentLevel)$($Identity -replace '^CN=|,(CN|OU|DC)=.+$')" -ForegroundColor "yellow"
$IndentLevel++
Get-QADGroupMember $Identity | ForEach-Object {
if ($_.Type -eq 'group') {
Get-GroupMemberTree $_.DN $IndentLevel $IndentCharacter
} else {
Write-Host "$($IndentCharacter * $IndentLevel)$($_.Name)"
}
}
}
Get-GroupMemberTree "Account Operators"
#This script will import a list of users fom a CSV file and compare te list against a given AD Group. Then it will
# 1) Add anyone who is the CSV but not in the AD group
# 2) Remove anyone in the AD Group but not in the CSV
Import-Module ActiveDirectory
#We will use Quest commandlets to simplify data pull from AD Group as Get-ADGroupMember has a size limit
Add-PSSnapin Quest.ActiveRoles.ADManagement
Set-QADPSSnapinSettings -DefaultPageSize 1000 -DefaultSizeLimit 0
$GroupName="TRUMP CABINET"
$NewMembers=Import-Csv "C:\temp\TrumpCabinetMembers.csv" -Header "SamAccountName" | Where-Object { $_.PSObject.Properties.Value -ne $null}
$ExistingMembers=Get-QADGroupMember -Identity $GroupName | Select-Object SamAccountName -ExpandProperty SamAccountName | Out-String -Stream
#Remove user from AD Group if they are not in the CSV
ForEach($Member in $ExistingMembers)
{If($NewMembers -notcontains $Member){
Remove-ADGroupMember -Identity $GroupName -Member $Member -Confirm:$false}}
#Add the user to the group if they are not a member
foreach ($NewMember in $NewMembers) {
If($NewMember -notin $ExistingMembers){
Try{Add-ADGroupMember -Identity $GroupName -Member $NewMember.SamAccountName | Out-String -Stream }
Catch{"Add-ADGroupMember : Cannot find an object with identity" > $null
#Export the username if not found in AD
$NewMember | Export-Csv C:\temp\UserNotFound_.csv -Append -NoClobber -NoTypeInformation > $null
}}}
#Have you ever wanted to verify which server in your Domain holds the FSMO roles?
#Wait no further and use this script to verify the FSMO , Schema and Domain Naming masters in your environment
Get-ADDomain | Select-Object InfrastructureMaster, RIDMaster, PDCEmulator
Get-ADForest | Select-Object DomainNamingMaster, SchemaMaster
Get-ADDomainController -Filter * |
Select-Object Name, Domain, Forest, OperationMasterRoles |
Where-Object {$_.OperationMasterRoles} |
Format-Table -AutoSize
#From here you can export the info or pipe it to automate or monitor things.
#hop you find it useful
#This script will clone the Group membership of one user to another
#Get groups of the source user
$SrouceUser="CN=John Snow (jsnow),OU=People,OU=Starks,OU=Castle Black,DC=Winterfell,DC=com"
#Get the user to whom you will be cloning groups to
$DestinationUser=Get-ADUser "CN=Tyrion Lannister,OU=People,OU=Lannisters,OU=Casterly Rock,DC=Winterfell,DC=com"
$Groups=Get-ADUser $SourceUser -Properties Memberof | Select-Object Memberof -ExpandProperty Memberof | Out-String -Stream
#Add the Destination user to these groups
ForEach($Group in $Groups)
{
Add-ADGroupMember -Identity $Group -Members $DestinationUser
}
#Use this sample script as a fix if you ever find yourself in a situation where membership of a DL is hidden and it is causing issues with your inhouse DL management tools or with Office 365 (because currently, O365 does not support hidden membership)
#This is mainly cuased because when this attribute was used in Exchange 2007 and prior, it made an explicit deny ACL entry for Everyone
#Enter the DL name
$DLName="PentagonSecurityLeads"
$DLdn=Get-ADGroup $DLName | Select -Property distinguishedname -ExpandProperty DistinguishedName
#Export members as a backup:
$Users=Get-ADGroupMember "$DLDn"
$Users | Export-Csv C:\Temp\$DLName.csv -NoTypeInformation
dsacls "$DLdn" /G Everyone:GR
Set-ADGroup "$DLdn" -Clear hideDLMembership
#Optionally move the Object somewhere else like a parent OU for DLs
Move-ADObject "$DLdn" -TargetPath "OU=Distribution Lists,DC=Washington,DC=Pentagon,DC=lab,DC=com"
#Ever find yourself looking at a whole bunch of groups thinking if anyone was recently added to these groups. Think no more and use this script to get the date a member was last added to the group
Function Get-ADGroupMemberDate {
<#
.SYNOPSIS
Provides the date that a member was added to a specified Active Directory group.
.DESCRIPTION
Provides the date that a member was added to a specified Active Directory group.
.PARAMETER Group
The group that will be inspected for members and date added. If a distinguished name (dn) is not used,
an attempt to get the dn before making the query.
.PARAMETER DomainController
Name of the domain controller to query. Optional parameter.
.NOTES
Name: Get-ADGroupMemberDate
Author: Boe Prox
DateCreated: 17 May 2013
Version 1.0
The State property will be one of the following:
PRESENT: User currently exists in group and the replicated using Linked Value Replication (LVR).
ABSENT: User has been removed from group and has not been garbage collected based on Tombstone Lifetime (TSL).
LEGACY: User currently exists as a member of the group but has no replication data via LVR.
.EXAMPLE
Get-ADGroupMemberDate -Group "Domain Admins" -DomainController DC3
ModifiedCount : 2
DomainController : DC3
LastModified : 5/4/2013 6:48:06 PM
Username : joesmith
State : ABSENT
Group : CN=Domain Admins,CN=Users,DC=Domain,DC=Com
ModifiedCount : 1
DomainController : DC3
LastModified : 1/6/2010 7:36:08 AM
Username : adminuser
State : PRESENT
Group : CN=Domain Admins,CN=Users,DC=Domain,DC=Com
...
Description
-----------
This lists out all of the members of Domain Admins using DC3 as the Domain Controller.
.EXAMPLE
Get-ADGroup -Identity "TestGroup" | Get-ADGroupMemberDate
ModifiedCount : 2
DomainController : DC1
LastModified : 5/4/2013 6:48:06 PM
Username : joesmith
State : ABSENT
Group : CN=TestGroup,OU=Groups,DC=Domain,DC=Com
ModifiedCount : 1
DomainController : DC1
LastModified : 1/6/2010 7:36:08 AM
Username : bobsmith
State : PRESENT
Group : CN=TestGroup,OU=Groups,DC=Domain,DC=Com
...
Description
-----------
This lists out all of the members of TestGroup from the output of Get-ADGroup and auto-selecting DC1 as the Domain Controller.
#>
[OutputType('ActiveDirectory.Group.Info')]
[cmdletbinding()]
Param (
[parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True,Mandatory=$True)]
[Alias('DistinguishedName')]
[string]$Group,
[parameter()]
[string]$DomainController = ($env:LOGONSERVER -replace "\\\\")
)
Begin {
#RegEx pattern for output
[regex]$pattern = '^(?<State>\w+)\s+member(?:\s(?<DateTime>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})\s+(?:.*\\)?(?<DC>\w+|(?:(?:\w{8}-(?:\w{4}-){3}\w{12})))\s+(?:\d+)\s+(?:\d+)\s+(?<Modified>\d+))?'
}
Process {
If ($Group -notmatch "^CN=.*") {
Write-Verbose "Attempting to get distinguished name of $Group"
Try {
$distinguishedName = ([adsisearcher]"name=$group").Findone().Properties['distinguishedname'][0]
If (-Not $distinguishedName) {Throw "Fail!"}
} Catch {
Write-Warning "Unable to locate $group"
Break
}
} Else {$distinguishedName = $Group}
Write-Verbose "Distinguished Name is $distinguishedName"
$data = (repadmin /showobjmeta $DomainController $distinguishedName | Select-String "^\w+\s+member" -Context 2)
ForEach ($rep in $data) {
If ($rep.line -match $pattern) {
$object = New-Object PSObject -Property @{
Username = [regex]::Matches($rep.context.postcontext,"CN=(?<Username>.*?),.*") | ForEach {$_.Groups['Username'].Value}
LastModified = If ($matches.DateTime) {[datetime]$matches.DateTime} Else {$Null}
DomainController = $matches.dc
Group = $distinguishedName
State = $matches.state
ModifiedCount = $matches.modified
}
$object.pstypenames.insert(0,'ActiveDirectory.Group.Info')
$object
}
}
}
}
$Groups=Get-ADGroup -SearchBase "OU=Groups,OU=Castle Black,OU=Starks,DC=Winterfell,DC=com" -Filter * -Properties Name,DistinguishedName,Members | Where-Object {$_.Members -ne $null} | Select Name,DistinguishedName,Members
ForEach ($Group in $Groups)
{
Get-ADGroupMemberDate -Group $Group.Name | Where-Object {$_.State -eq "PRESENT"} | Sort LastModified -Descending | Select -First 1 @{label='Group';expression={$_.Group -replace '^CN=|,.*$'}},@{Expression={([datetime]$_.LastModified).ToShortDateString()};Label="LastMemberAdded"},@{label='User';expression={$_.Username}} | Export-Csv C:\Temp\Groups.csv -Append -NoTypeInformation
}
#Have you ever been asked to export members from multipe groups.
#Back in the day you would export them using ADExport or some manual tool
#Today you can do that with powershell. But wait, what if you could export all groups and members to the same CSV file without having to VLOOKUP in Excel?
#Wait no more, use the powershell script below to easily export AD group members and map them to their respective group
Add-PSSnapin Quest.ActiveRoles.ADManagement;Set-QADPSSnapinSettings -DefaultPageSize 100 -DefaultSizeLimit 0
#Get all groups in an OU
$Groups=Get-QADGroup -SearchRoot "OU=Groups,OU=Castle Black,OU=Starks,DC=Winterfell,DC=com" | Select Name,DN
#If you want to focus on just one group and it's nested groups\
$Groups=Get-QADGroupMember "LannisterOrganization" -Indirect -Type group | Select Name,DN
Foreach ($Group in $Groups)
{
Get-QADGroupMember -Identity $Group.DN | Get-QADObject -Properties name,mail,samaccountname |
Select @{Label="GroupName";Expression={$Group.Name}},name,mail,samaccountname |
Export-Csv c:\temp\LannisterGroupsMapping.csv -Append -NoTypeInformation
}
#Create Temp folder on root of C drive if it doesn't exist
If (!(Test-Path C:\Temp\)) {New-Item -Path "C:\Temp\" -ItemType Directory -Force}
#Requires Quest Active Directory Management Tools
Add-PSSnapin Quest.ActiveRoles.ADManagement
#VERY IMPORTANT: Always backup existing ACLs first before making any changes
#This commandlet will show all Security ACL Permissions for a given AD Object
Get-QADObject "OU=Washington,DC=Pentagon,DC=USA,DC=COM" -SecurityMask Dacl | Get-QADPermission | Export-Csv C:\Temp\Root-Permimissions.csv
#This is another way of doing the above. Replace DomainDNSRoot with your Domain name like lab.domain.local
Get-QADPermission -Identity "DomainDNSRoot/" | Export-Csv C:\Temp\Root-Permimissions.csv
#The following will get permissions a User/Group has on all OUs within the domain
$OUs=Get-ADOrganizationalUnit -FILter * | Select-Object DistinguishedName -ExpandProperty DistinguishedName
ForEach ($OU in $OUs){
Get-QADPermission -Identity "$OU" -Account "DomainNetBIOSName\jfkennedy"
#If you wanted to remove those permissions just pipe it like below but remove -whatif parameter
Get-QADPermission -Identity "$OU" -Account "DomainNetBIOSName\jfkennedy" | Remove-QADPermission -WhatIf
}
<#Active Directory Domain Services uses AdminSDHolder, protected groups and Security Descriptor propagator (SD propagator or SDPROP for short) to secure privileged users and groups from unintentional modification. This functionality was introduced in the inaugural release of Active Directory in Windows 2000 Server and it's fairly well known. However, virtually all IT administrators have been negatively impacted by this functionality, and that will to continue unless they fully understand how AdminSDHolder, protected groups and SDPROP work
Simply put let's Bob is a Domain Admin
Because of this AD assigns the adminCount attribute a value of 1 which protects anyone but a Domain Admin modify Bob's account
When we remove Bob from Domain Admins group, his AD Account is still protected because the attribute is not cleared by default, we have to do it manually. That's where this script comes into place
Read more about AdminCount here https://technet.microsoft.com/en-us/magazine/2009.09.sdadminholder.aspx
This PowerShell script will perform the following actions on an Active Directory Object
1) Clear AdminCount attribute
2) Assign ownership of the Object to Domain Admins
3) Grant Domain Admin Full Permissions (In some occasions I have noticed you need to first grant Full Permissions to Domain Admins and then
restore default. Haven't seen the occurence again so couldn't investigate)
4) Restore default permissions.
#>
#Even though the commands in this script are starightforward, we will stop the script if there are any errors
$ErrorActionPreference="Stop"
#Specify the OU to search for Admin Users and Groups
$OU="OU=People,OU=Starks,OU=Castle Black,DC=Winterfell,DC=com"
#Specify the path for reports for a list of AD Objects being modified and their ACLs
$ReportPath="$env:USERPROFILE"
$AdminObjects=Get-ADObject -SearchBase $OU -Filter {adminCount -eq "1"} | Select DistinguishedName -ExpandProperty DistinguishedName
#Export the current list as a precaution
$AdminObjects | Out-File "$ReportPath\AdminObjects.csv"
#Now lets do the magic
ForEach ($Admin in $AdminObjects) {
#Oh Wait, let's export the current ACL of these objects as a backup.
#You never know that one admin from 20 years ago could have set some weird permissions
(Get-ACL "AD:$($Admin)").access | Select @{Expression={$Admin};Label="AdminObject"},* | Export-Csv "$ReportPath\AdminObject_SecurityACL.csv" -Append -NoTypeInformation
#First clear the admincount attribute so the protection is removed
Set-ADObject "$Admin" -Clear "adminCount"
#Assign ownerhsip to Domain Admins
DSACLS "$Admin" /takeownership
#Grant Domain Admins full permissions
DSACLS "$Admin" /G '"Domain Admins":GA'
#Reset Default ACL
DSACLS "$Admin" /resetDefaultDACL
}
#OU Where the users need to be created
$Path = "OU=Marketing,OU=AllUsers,DC=AutomationJunkie,DC=com"
#import the CSV with list of users
$Accounts = Import-Csv C:\Temp\Users.csv
#if your csv does not have headers
#$Accounts = Import-Csv C:\Temp\Users.csv -Header @("DisplayName","Userprincipalname","givenname","sn","SamAccountName","Name","employeeID")
foreach ($line in $Accounts)
{
#Lets create the Users and input the name, display name, description and first name
New-ADUser -Path $Path -Name $line.Name -SamAccountName $line.SamAccountName -DisplayName $line.DisplayName -GivenName $line.givenname -Surname $line.sn -UserPrincipalName $line.Userprincipalname -EmployeeID $line.employeeID -ChangePasswordAtLogon $true -Enabled $True -AccountPassword (ConvertTo-SecureString -AsPlainText "SuperSecure@123!!!" -Force) -Verbose
}
#if you need to reset their password
Set-ADAccountPassword -Identity $line.Name -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "SuperSecure@123!!!" -Force)
##############################################################################################
## Find out what computers a user is logged into on your domain by running the script
## and entering in the requested logon id for the user.
##
## This script requires the free Quest ActiveRoles Management Shell for Active Directory
## snapin http://www.quest.com/powershell/activeroles-server.aspx
##############################################################################################
Add-PSSnapin Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue
$ErrorActionPreference = "SilentlyContinue"
# Retrieve Username to search for, error checks to make sure the username
# is not blank and that it exists in Active Directory
Function Get-Username {
$Global:Username = Read-Host "Enter username you want to search for"
if ($Username -eq $null){
Write-Host "Username cannot be blank, please re-enter username!!!!!"
Get-Username}
$UserCheck = Get-QADUser -SamAccountName $Username
if ($UserCheck -eq $null){
Write-Host "Invalid username, please verify this is the logon id for the account"
Get-Username}
}
get-username
$computers = Get-QADComputer | where {$_.accountisdisabled -eq $false}
foreach ($comp in $computers)
{
$Computer = $comp.Name
$ping = new-object System.Net.NetworkInformation.Ping
$Reply = $null
$Reply = $ping.send($Computer)
if($Reply.status -like 'Success'){
#Get explorer.exe processes
$proc = gwmi win32_process -computer $Computer -Filter "Name = 'explorer.exe'"
#Search collection of processes for username
ForEach ($p in $proc) {
$temp = ($p.GetOwner()).User
if ($temp -eq $Username){
write-host "$Username is logged on $Computer"
}}}}
Import-Module AciveDirectory
#Force the password to expire. use the user's distinguishedName
Set-ADUser "CN=Nikki Bella,OU=RealEstate,OU=AllUsers,DC=AutomationJunkie,DC=com" -Replace @{pwdLastSet='0'}
#Get info is password is expired
Get-ADUser "CN=John Cena,OU=WeightLifting,OU=AllUsers,DC=AutomationJunkie,DC=com" -Properties PasswordExpired | Select-Object PasswordExpired
Set-ADUser "shamitchell" -Replace @{pwdLastSet='0'}
Get-ADUser "shamitchell" -Properties PasswordExpired | Select-Object PasswordExpired
#Get Domain List and load user e-mails from file
Get-Module ActiveDirectory | Import-Module
$objForest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$DomainList = @($objForest.Domains | Select-Object Name)
$Domains = $DomainList | foreach {$_.Name}
$Users = Import-CSV c:\temp\evamarie\TEST.csv
#Act on each domain
foreach($Domain in $Domains)
{
Write-Host "Checking $Domain" -fore red
foreach ($line in $users)
{
Get-ADUser -identity $line.SamAccountName -Server $domain -Properties "Name" | select-object -ExpandProperty "Name"
}
}
Get-Module ActiveDirectory | Import-Module
Get-ADUser -Identity ikhan -Properties directreports | Select-Object -ExpandProperty directreports | Get-ADUser -Properties Name,mail | Select-Object Name,mail
#Resolve or get SID for Active Directory object
#Resolve object SID to username
$objSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-21-123456789-1234567890-123456789-12345") $objUser = $objSID.Translate( [System.Security.Principal.NTAccount]) $objUser.Value
$objSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-21-123456789-1234567890-123456789-12345")
$objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
$objUser.Value
#Get SID of a username
get-aduser "username" -Properties sid | select sid
#Script (with Quest Active Directory module) :
Get-QADUser "username" -IncludedProperties sid |select sid
(Get-ACL "AD:$((Get-ADUser james).distinguishedname)").access
#requires -version 3.0
# Show a user's group memberships and the dates they were added to those groups.
Import-Module ActiveDirectory
$username = "jsnow"
$userobj = Get-ADUser $username
$DC = (Get-ADDomainController -Discover | Select-Object HostName -ExpandProperty HostName)
Get-ADUser $userobj.DistinguishedName -Properties memberOf |
Select-Object -ExpandProperty memberOf |
ForEach-Object {
Get-ADReplicationAttributeMetadata $_ -Server $DC -ShowAllLinkedValues |
Where-Object {$_.AttributeName -eq 'member' -and
$_.AttributeValue -eq $userobj.DistinguishedName} |
Select-Object FirstOriginatingCreateTime, Object, AttributeValue
} | Sort-Object FirstOriginatingCreateTime -Descending | Out-GridView
###############################################################################
# Here are some one-liners for exploring:
#Get-ADUser 'CN=jsnow,OU=Migrated,DC=CohoVineyard,DC=com' -Properties memberOf
#Get-ADGroup 'CN=Legal,OU=Groups,DC=CohoVineyard,DC=com' -Properties member, members, memberOf
#Get-ADReplicationAttributeMetadata 'CN=Legal,OU=Groups,DC=CohoVineyard,DC=com' -Server $DC -ShowAllLinkedValues | Out-GridView
###############################################################################
# This works at the cmd line but not in PS console.
# However, it does not include the date data.
#Repadmin.exe /showobjmeta localhost "CN=Legal,OU=Migrated,DC=CohoVineyard,DC=com" | find /i "jsnow"
###############################################################################
#Get AD users in subdivision technology whose location is blank
Get-ADUser -LDAPFilter "(&(subdivision= Technology)(!l=*))" -Properties * | Select-Object DisplayName,mail,co | Sort-Object co | Export-Csv TechnologyTeam_No-Location.csv
##https://gallery.technet.microsoft.com/scriptcenter/How-to-find-locked-out-1d964f6b
If($SamAccountName)
{
Foreach($Account in $SamAccountName)
{
$LockedOutAccount = Get-ADUser -Filter {SamAccountName -eq $Account} -Server $DC.HostName `
-Properties SamAccountName,AccountLockoutTime,LastBadPasswordAttempt,badPwdCount,LockedOut|`
Where{$_.LockedOut -eq $true} | Select-Object SamAccountName,AccountLockoutTime,LastBadPasswordAttempt,badPwdCount,LockedOut
$LockedOutInfo = $LockedOutAccount|Foreach{New-Object -TypeName PSObject `
-Property @{SamAccountName = $_.SamAccountName;
LogonLocation = $($Name = $_.SamAccountName;`
$Objs|Where{$_.SamAccountName -eq $Name}|Sort -Unique|`
Select -ExpandProperty Location);
AccountLockoutTime = $_.AccountLockoutTime
LastBadPasswordAttempt = $_.LastBadPasswordAttempt;
badPwdCount = $_.badPwdCount}}
$LockedOutInfo | Select SamAccountName,LogonLocation,AccountLockoutTime,LastBadPasswordAttempt,badPwdCount
}
}
#This LDAP filter can be used to chain match a org heirarchy of a User within Active Directory
#For instance it can help in pulling information for everyone under a leader's Org
#You can use this filter in a script to build Automated AD Groups
#This rule is limited to filters that apply to the DN. This is a special "extended" match operator that walks the chain of ancestry in objects all the way to the root until it finds a match.
Get-ADUser -LDAPFilter "(&(objectCategory=person)(objectClass=user)(manager:1.2.840.113556.1.4.1941:=CN=Satya Cannister,OU=Delhi,DC=dev,DC=lab,DC=com))"
###Launch PowerShell as Administrator on any Domain COntroller
Import-Module ActiveDirectory
#First check if the object exists
Get-ADObject -Filter {samaccountname -eq "DwayneJohnson"} -IncludeDeletedObjects
#If it does, restore the object
Get-ADObject -Filter {samaccountname -eq "DwayneJohnson"} -IncludeDeletedObjects | Restore-ADObject
#Using native AD module
Import-Module ActiveDirectory
Set-ADUser johnsnow -Replace @{homepostaladdress='TEST_Address'}
Get-ADUser johnsnow -Property homepostaladdress | Select-Object -Property homepostaladdress
#To clear an attribute
Set-ADUser johnsnow -clear homepostaladdress
##Using Quest Active Roles Management Shell from https://support.software.dell.com/download-install-detail/5024645
Add-PSSnapin -Name Quest.ActiveRoles.ADManagement
$UserList = Import-CSV C:\temp\UserList.CSV -Header @("SamAccountName","homePostalAddress")
foreach ($line in $UserList)
{
Write-Host $line | Format-Table
Set-QADUser -Identity $line.SamAccountname -ObjectAttributes @{homepostaladdress=$line.homePostalAddress}
#Haven't had time to include error handling yet but some day I will I promise :)
#Using PowerShell and ADSI
$DomainName = "Get-ADDomain | Select dnsroot -ExpandProperty dnsroot"
$ComputerName = "Server1"
$UserName = "username"
$AdminGroup = [ADSI]"WinNT://$ComputerName/Administrators,group"
$User = [ADSI]"WinNT://$DomainName/$UserName,user"
$AdminGroup.Add($User.Path)
#Using PSEXEC and CMD
psexec \\ComputerName net localgroup Administrators "DomainName\UserName" /add
#Add user to multiple computers
$ErrorActionPreference="SilentlyContinue"
$DomainName=Get-ADDomain | Select dnsroot -ExpandProperty dnsroot
$Computers="Server1","Server2","Server3"
$UserName ="username"
#Try both username and domain\username. It will work based on if the account is local or AD object
$User = [ADSI]"WinNT://$DomainName/$UserName,user"
ForEach($Computer in $Computers){
$AdminGroup = [ADSI]"WinNT://$Computer/Administrators,group"
$AdminGroup.Add($User.Path)
}
#Step 1: Launch elevated Prompt. To do this, type CMD in Windows 7 Start menu search box and simultaneously press Ctrl + Shift + Enter keys. Windows 8 users can simply type CMD in Start screen and then press Ctrl + Shift + Enter to launch Command Prompt with admin rights.
#Step 2: In the elevated prompt, type the following command:
rd /s c:\$Recycle.Bin
#(In the above command, “c” is your Windows drive)
#Powershell Script To Install SNMP Services (SNMP Service, SNMP WMI Provider)
#Variables :)
$pmanagers = "HPSIMSERVER001"
$commstring = "CORPWINTRAP"
#Import ServerManger Module
Import-Module ServerManager
#Check If SNMP Services Are Already Installed
$check = Get-WindowsFeature | Where-Object {$_.Name -eq "SNMP-Services"}
If ($check.Installed -ne "True") {
#Install/Enable SNMP Services
Add-WindowsFeature SNMP-Services | Out-Null
}
##Verify Windows Servcies Are Enabled
If ($check.Installed -eq "True"){
#Set SNMP Permitted Manager(s) ** WARNING : This will over write current settings **
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SNMP\Parameters\PermittedManagers" /v 1 /t REG_SZ /d localhost /f | Out-Null
#Used as counter for incremting permitted managers
$i = 2
Foreach ($manager in $pmanagers){
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SNMP\Parameters\PermittedManagers" /v $i /t REG_SZ /d $manager /f | Out-Null
$i++
}
#Set SNMP Community String(s)- *Read Only*
Foreach ( $string in $commstring){
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SNMP\Parameters\ValidCommunities" /v $string /t REG_DWORD /d 4 /f | Out-Null
}
}
Else {Write-Host "Error: SNMP Services Not Installed"}
function Get-HPArrayDisks
{
<#
.SYNOPSIS
Retrieves physical hard disk information for HP servers.
.DESCRIPTION
The Get-HPArrayDisks function works through WMI and requires
that the HP Insight Management WBEM Providers are installed on
the server that is being quiered.
.PARAMETER Computername
The HP server for which the disks should be listed.
This parameter is optional and if the parameter isn't specified
the command defaults to local machine.
First positional parameter.
.EXAMPLE
Get-HPArrayDisks
Lists physical disk information for the local machine
.EXAMPLE
Get-HPArrayDisks SRV-HP-A
Lists physical disk information for server SRV-HP-A
.EXAMPLE
"SRV-HP-A", "SRV-HP-B", "SRV-HP-C" | Get-HPArrayDisks
Lists physical disk information for three servers
#>
[CmdletBinding(SupportsShouldProcess=$true)]
Param(
[Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position = 1)][string]$Computername=$env:computername
)
Process{
if ($pscmdlet.ShouldProcess("List disks on server " +$Computername)){
$diskdrives = Get-WmiObject -Computername $ComputerName -Namespace root\hpq -Query "select * from HPSA_DiskDrive"
ForEach ($disk in $diskdrives){
$OutObject = New-Object System.Object
$OutObject | Add-Member -type NoteProperty -name ComputerName -value $ComputerName
$OutObject | Add-Member -type NoteProperty -name Slot -value $disk.ElementName
$OutObject | Add-Member -type NoteProperty -name Interface -value $disk.Description
$OutObject | Add-Member -type NoteProperty -name RotationalSpeed -value $disk.DriveRotationalSpeed
$drivePhys = Get-WmiObject -Computername $ComputerName -Namespace root\hpq -Query ("ASSOCIATORS OF {HPSA_DiskDrive.CreationClassName='HPSA_DiskDrive',DeviceID='" + $disk.DeviceID + "',SystemCreationClassName='" + $disk.SystemCreationClassName + "',SystemName='" + $disk.SystemName + "'} WHERE AssocClass=HPSA_DiskPhysicalPackageDiskDrive")
$OutObject | Add-Member -type NoteProperty -name Model -value $drivePhys.Model
$OutObject | Add-Member -type NoteProperty -name SerialNumber -value $drivePhys.SerialNumber.trim()
$driveFW = Get-WmiObject -Computername $ComputerName -Namespace root\hpq -Query ("ASSOCIATORS OF {HPSA_DiskDrive.CreationClassName='HPSA_DiskDrive',DeviceID='" + $disk.DeviceID + "',SystemCreationClassName='" + $disk.SystemCreationClassName + "',SystemName='" + $disk.SystemName + "'} WHERE AssocClass=HPSA_DiskDriveDiskDriveFirmware")
$OutObject | Add-Member -type NoteProperty -name FirmwareVersion -value $driveFW.VersionString.trim()
$driveStorage = Get-WmiObject -Computername $ComputerName -Namespace root\hpq -Query ("ASSOCIATORS OF {HPSA_DiskDrive.CreationClassName='HPSA_DiskDrive',DeviceID='" + $disk.DeviceID + "',SystemCreationClassName='" + $disk.SystemCreationClassName + "',SystemName='" + $disk.SystemName + "'} WHERE AssocClass=HPSA_DiskDriveStorageExtent")
$OutObject | Add-Member -type NoteProperty -name SizeInGigabytes -value ([math]::round(($driveStorage.BlockSize * $driveStorage.NumberOfBlocks) / 1000000000))
$OutObject | Add-Member -type NoteProperty -name PowerOnHours -value $driveStorage.TotalPowerOnHours
Write-Output $OutObject
}
}
}
}
Get-WmiObject Win32_PnPSignedDriver| select devicename, driverversion | where {$_.devicename -like "*nvidia*"}
$name = (Get-Item env:\Computername).Value
$filepath = (Get-ChildItem env:\userprofile).value
## Email Setting
$smtp = "Your-ExchangeServer"
$to = "YourIT@YourDomain.com"
$subject = "Hardware Info of $name"
$attachment = "$filepath\$name.html"
$from = (Get-Item env:\username).Value + "@yourdomain.com"
#### HTML Output Formatting #######
$a = "<style>"
$a = $a + "BODY{background-color:Lavender ;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:thistle}"
$a = $a + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:PaleGoldenrod}"
$a = $a + "</style>"
###############################################
ConvertTo-Html -Head $a -Title "Hardware Information for $name" -Body "<h1> Computer Name : $name </h1>" > "$filepath\$name.html"
# MotherBoard: Win32_BaseBoard # You can Also select Tag,Weight,Width
Get-WmiObject -ComputerName $name Win32_BaseBoard | Select Name,Manufacturer,Product,SerialNumber,Status | ConvertTo-html -Body "<H2> MotherBoard Information</H2>" >> "$filepath\$name.html"
# Battery
Get-WmiObject Win32_Battery -ComputerName $name | Select Caption,Name,DesignVoltage,DeviceID,EstimatedChargeRemaining,EstimatedRunTime | ConvertTo-html -Body "<H2> Battery Information</H2>" >> "$filepath\$name.html"
# BIOS
Get-WmiObject win32_bios -ComputerName $name | Select Manufacturer,Name,BIOSVersion,ListOfLanguages,PrimaryBIOS,ReleaseDate,SMBIOSBIOSVersion,SMBIOSMajorVersion,SMBIOSMinorVersion | ConvertTo-html -Body "<H2> BIOS Information </H2>" >> "$filepath\$name.html"
# CD ROM Drive
Get-WmiObject Win32_CDROMDrive -ComputerName $name | select Name,Drive,MediaLoaded,MediaType,MfrAssignedRevisionLevel | ConvertTo-html -Body "<H2> CD ROM Information</H2>" >> "$filepath\$name.html"
# System Info
Get-WmiObject Win32_ComputerSystemProduct -ComputerName $name | Select Vendor,Version,Name,IdentifyingNumber,UUID | ConvertTo-html -Body "<H2> System Information </H2>" >> "$filepath\$name.html"
# Hard-Disk
Get-WmiObject win32_diskDrive -ComputerName $name | select Model,SerialNumber,InterfaceType,Size,Partitions | ConvertTo-html -Body "<H2> Harddisk Information </H2>" >> "$filepath\$name.html"
# NetWord Adapters -ComputerName $name
Get-WmiObject win32_networkadapter -ComputerName $name | Select Name,Manufacturer,Description ,AdapterType,Speed,MACAddress,NetConnectionID | ConvertTo-html -Body "<H2> Nerwork Card Information</H2>" >> "$filepath\$name.html"
# Memory
Get-WmiObject Win32_PhysicalMemory -ComputerName $name | select BankLabel,DeviceLocator,Capacity,Manufacturer,PartNumber,SerialNumber,Speed | ConvertTo-html -Body "<H2> Physical Memory Information</H2>" >> "$filepath\$name.html"
# Processor
Get-WmiObject Win32_Processor -ComputerName $name | Select Name,Manufacturer,Caption,DeviceID,CurrentClockSpeed,CurrentVoltage,DataWidth,L2CacheSize,L3CacheSize,NumberOfCores,NumberOfLogicalProcessors,Status | ConvertTo-html -Body "<H2> CPU Information</H2>" >> "$filepath\$name.html"
## System enclosure
Get-WmiObject Win32_SystemEnclosure -ComputerName $name | Select Tag,AudibleAlarm,ChassisTypes,HeatGeneration,HotSwappable,InstallDate,LockPresent,PoweredOn,PartNumber,SerialNumber | ConvertTo-html -Body "<H2> System Enclosure Information </H2>" >> "$filepath\$name.html"
## Invoke Expressons
invoke-Expression "$filepath\$name.html"
#### Sending Email
Send-MailMessage -To $to -Subject $subject -From $from $subject -SmtpServer $smtp -Priority "High" -BodyAsHtml -Attachments "$filepath\$name.html"
Get-WMIObject Win32_operatingsystem -ComputerName Server1.domain.local | select csname,@{LABEL='lastbootuptime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}
@echo off
Rundll32.exe User32.dll,LockWorkStation
exit
<#
IMPORTANT: Someone gave this script to me at some point long long time ago and I haven't really vetted it. Use with caution and always test in your lab first.
##Info
This script might be usefull when you need to make significant changes into infrastructure addressing scheme and want to to find out which computers would not be affected by DHCP changes. It uses Get-ADComputer Cmdlet with LDAPFilter, which can be easily replaced into something different, providing list of computer names.
#>
param (
[string]$LDAPFilter = '(name=*)',
[switch]$Verbose
)
Get-ADComputer -LDAPFilter $LDAPFilter |
% `
{
$name = $_.DNSHostName;
if ($Verbose.IsPresent)
{ Write-Host -ForegroundColor Yellow "Connecting to $name..." }
$ints = Get-WmiObject -ErrorAction SilentlyContinue -ComputerName $name `
-Query "select IPAddress, DefaultIPGateway from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE and DHCPEnabled=FALSE";
if ($ints -ne $null)
{
foreach ($int in $ints)
{
foreach ($addr in $int.IPAddress)
{
$ip = $null
if ($addr -match "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}")
{
$ip = $addr
$gw = $null
foreach ($gw_addr in $int.DefaultIPGateway)
{
if ($gw_addr -match "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}")
{
$gw = $gw_addr
break
}
}
if ($ip -ne $null)
{
$info = New-Object PSObject -Property `
@{
Name = $name
IP = $ip
Gateway = $gw
}
$info
if ($Verbose.IsPresent)
{ Write-Host -ForegroundColor Yellow $info }
}
}
}
}
}
} |
Select-Object Name, IP, Gateway
#Usage Examples:
#Returns all domain computers
.\ComputersWithStaticIP.ps1 '(name=*)'
#Stores all computers with name, contining "dc" into variable and displays progress output
$computersInfo = .\ComputersWithStaticIP.ps1 '(name="*dc*")' -Verbose
#Remotely Test Ports for multiple computers
#requires -Version 2
$ComputerList = Get-Content -Path $env:USERPROFILE\Documents\PC-List.txt | Sort-Object
$IPAddress = '10.1.1.71'
$Port = 1688
$ErrorActionPreference = 'Stop'
Function Test-SocketConnection
{
<#
.SYNOPSIS
Opens a socket connection to a remote system to test if the port is open.
.DESCRIPTION
Tests the connection from a remote system to another remote systme over a specified port.
This is useful to test if the port has been opened through the firewall.
.EXAMPLE
Test-SocketConnection -ComputerName Server01 -Destination Server02 -PortNumber 80
Tests a connection from Server01 to Server02 on port 80.
.EXAMPLE
Test-SocketConnection -ComputerName Server01 -Destination 10.1.1.71 -PortNumber 1688
Tests a connection from Server01 to 10.1.1.71 over port 1688.
.EXAMPLE
Test-SocketConnection -Destination SQLServer2 -PortNumber 1433
Creates a test connection from the local PC (where script runs) to SQLServer2 on port 1433.
.PARAMETER ComputerName
The name of the computer where the socket connection is initiated. Defaults to the local PC. Accepts an array of names as well.
.PARAMETER Destination
This is the target system to open the socket connection to. Hostname or IP are accepted.
.PARAMETER PortNumber
The port number that the socket connection will be opened through. Should be opened through the firewall on both sides.
#>
[cmdletbinding()]
Param(
[string[]]$ComputerName = $env:COMPUTERNAME,
[Parameter(Mandatory = $true)][string]$Destination,
[Parameter(Mandatory = $true)][Int]$PortNumber
)
$code =
{
[CmdletBinding()]
Param(
[String]$Destination,
[int]$PortNumber
)
Try
{
$socket = New-Object -TypeName net.sockets.tcpclient -ArgumentList ($Destination, $PortNumber) -Verbose
$output = New-Object -TypeName PSObject -Property @{
ComputerName = $env:COMPUTERNAME
Connected = $socket.Connected
}
$socket.Dispose()
}
Catch
{
$output = New-Object -TypeName PSObject -Property @{
ComputerName = $env:COMPUTERNAME
Connected = $false
}
}
Finally
{
Write-Output -InputObject $output
}
}
$out = @()
Write-Verbose 'ComputerName Connected'
foreach ($PC in $ComputerName)
{
try
{
$output = Invoke-Command -ComputerName $PC -ScriptBlock $code -ArgumentList $Destination, $PortNumber -Verbose -ErrorAction Stop
$display = $PC + ' ' + $output.Connected
Write-Verbose $display
}
catch
{
$output = New-Object -TypeName PSObject -Property @{
ComputerName = $PC
Connected = $false
}
Write-Error -Message "Unable to connect to $PC" -ErrorAction Continue
}
$out += $output
}
Write-Output -InputObject $out
}
$results = Test-SocketConnection -ComputerName $ComputerList -Destination $IPAddress -PortNumber $Port -Verbose
$results | Format-Table -Property ComputerName, Connected
Get-ChildItem D:\Users\zorro\Downloads\PSWindowsUpdate\ | Unblock-File
#Typically LDAP timestamps come in this weird long number format.
#This may be the case specifically when exporting AD Object information like Whencreated, lastChanged, PwdLastSet etc
#This time stamp though can easily be changed to a human readable format
#Lets consider the following example
$LDAPTimeStamp="131188565190084028"
#Now convert the time format
[datetime]::FromFileTime($LDAPTimeStamp).ToShortDateString()
#Boom, thats it, there is nothing more to do. Your job is done.
#Get Distributed File System (DFS) Group Member Servers
$GroupName = "DragonEmporer"
$Server_List = get-DfsrMember -Groupname $GroupName | Sort-Object ComputerName | Select-Object -Property DNSName
#From here you can either just export the list or do a ForEach and perform some actions
#Add all Exchange Snapins so we can run the exchange commandlets
Add-PSSnapin *EXchange*
#In this scenario we will get all groups in an OU
$GROUPS=Get-ADGroup -LDAPFilter "(&(&(&(objectCategory=group)(objectClass=group)(mail=*)(!dLMemSubmitPerms=*))))" -SearchBase "OU=Groups,OU=Castle Black,OU=Starks,DC=Winterfell,DC=com"
ForEach ($Group in $GROUPS)
{
Set-DistributionGroup -Identity $Group.DistinguishedName -AcceptMessagesOnlyFromSendersOrMembers "DLSendRights_Group" -Verbose -Confirm:$false -ForceUpgrade
}
#How do you know if this worked?
ForEach($Group in $GROUPS)
{
If ((Get-DistributionGroup $Group.DistinguishedName | Select-Object "AcceptMessagesOnlyFromSendersOrMember") -eq '$null')
{
Write-Host $Group.Name
#If you dont get any results back then you are set
}
}
}
#Another quicker way to check is
Get-DistributionGroup -OrganizationalUnit "OU=Groups,OU=Castle Black,OU=Starks,DC=Winterfell,DC=com" -ResultSize 10000 |
Where {$_.AcceptMessagesOnlyFromSendersOrMembers -eq '$null'}
#How to allow anyone (internal or external to be able to email a Distribution Group (List)
#Not restricting Distribution Groups to accept messages from specific external senders only
$ErrorActionPreference="Stop"
Import-Module ActiveDirectory
Add-PSSnapin "*Exchange*"
#Get all groups that you need to set the value to false
#You could also use Exchange commandlet Get-DistributionGroup with the OrganizationalUnit parameter
$Groups=Get-ADGroup -SearchBase "CN=Starks,OU=Groups,OU=Castle Black,OU=Starks,DC=Winterfell,DC=com" -ResultPageSize 10 -ResultSetSize $null -LdapFilter "(&(mail=*))"
ForEach ($Group in $Groups)
{Set-DistributionGroup -IgnoreNamingPolicy:$true -Identity $Group.Name -RequireSenderAuthenticationEnabled:$false -ForceUpgrade -BypassSecurityGroupManagerCheck}
$NestedGroups=Get-ADGroupMember -Recursive $Group.Name | Where-Object {$_.objectClass -eq "group"}
ForEach ($NGroup in $NestedGroups)
{Set-DistributionGroup -IgnoreNamingPolicy:$true -Identity $NGroup.Name -RequireSenderAuthenticationEnabled:$false -ForceUpgrade -BypassSecurityGroupManagerCheck}
#To check if this worked
#Get-DistributionGroup -Identity $Group.Name | Select RequireSenderAuthenticationEnabled
#Version1. Version2 will contain parameters for Share name. I got a few errors when trying to work around that and then didnt have time
# Configures the folders to have necessary SHARE permissions
# Set the folder path of the share
$Server = "FileServer001"
$SharedFolder = "C:\TESTEST"
# Assign the Share Permissions
# User Name/Group to give permissions to
$trustee = ([wmiclass]'Win32_trustee').psbase.CreateInstance()
$trustee.Domain = "winterfell.com"
$trustee.Name = "Cersei Lannister"
$trustee2 = ([wmiclass]'Win32_trustee').psbase.CreateInstance()
$trustee2.Domain = "winterfell.com"
$trustee2.Name = "Tyrion Lannister"
# Access mask values
$fullcontrol = 2032127
$change = 1245631
$read = 1179785
# Create access-list for trustee
$ace = ([wmiclass]'Win32_ACE').psbase.CreateInstance()
$ace.AccessMask = $fullcontrol
$ace.AceFlags = 3
$ace.AceType = 0
$ace.Trustee = $trustee
# Create access-list for trustee2
$ace2 = ([wmiclass]'Win32_ACE').psbase.CreateInstance()
$ace2.AccessMask = $Read
$ace2.AceFlags = 3
$ace2.AceType = 0
$ace2.Trustee = $trustee2
# Security descriptor containing access
$sd = ([wmiclass]'Win32_SecurityDescriptor').psbase.CreateInstance()
$sd.ControlFlags = 4
$sd.DACL = $ace, $ace2
$sd.group = $trustee
$sd.owner = $trustee
$share = Get-WmiObject Win32_Share -List -ComputerName "$Server"
$share.create("$SharedFolder", "TESTEST$", 0, 100, "SHARE_NAME", "", $sd)
Function Get-FolderItem {
<#
.SYNOPSIS
Lists all files under a specified folder regardless of character limitation on path depth.
.DESCRIPTION
Lists all files under a specified folder regardless of character limitation on path depth.
.PARAMETER Path
The type name to list out available constructors and parameters
.PARAMETER Filter
Optional parameter to specify a specific file or file type. Wildcards (*) allowed.
Default is '*.*'
.PARAMETER ExcludeFile
Exclude Files matching given names/paths/wildcards
.PARAMETER MaxAge
Exclude files older than n days.
.PARAMETER MinAge
Exclude files newer than n days.
.EXAMPLE
Get-FolderItem -Path "C:\users\Administrator\Desktop\PowerShell Scripts"
LastWriteTime : 4/25/2012 12:08:06 PM
FullName : C:\users\Administrator\Desktop\PowerShell Scripts\3_LevelDeep_ACL.ps1
Name : 3_LevelDeep_ACL.ps1
ParentFolder : C:\users\Administrator\Desktop\PowerShell Scripts
Length : 4958
LastWriteTime : 5/29/2012 6:30:18 PM
FullName : C:\users\Administrator\Desktop\PowerShell Scripts\AccountAdded.ps1
Name : AccountAdded.ps1
ParentFolder : C:\users\Administrator\Desktop\PowerShell Scripts
Length : 760
LastWriteTime : 4/24/2012 5:48:57 PM
FullName : C:\users\Administrator\Desktop\PowerShell Scripts\AccountCreate.ps1
Name : AccountCreate.ps1
ParentFolder : C:\users\Administrator\Desktop\PowerShell Scripts
Length : 52812
Description
-----------
Returns all files under the PowerShell Scripts folder.
.EXAMPLE
$files = Get-ChildItem | Get-FolderItem
$files | Group-Object ParentFolder | Select Count,Name
Count Name
----- ----
95 C:\users\Administrator\Desktop\2012 12 06 SysInt
15 C:\users\Administrator\Desktop\DataMove
5 C:\users\Administrator\Desktop\HTMLReportsinPowerShell
31 C:\users\Administrator\Desktop\PoshPAIG_2_0_1
30 C:\users\Administrator\Desktop\PoshPAIG_2_1_3
67 C:\users\Administrator\Desktop\PoshWSUS_2_1
437 C:\users\Administrator\Desktop\PowerShell Scripts
9 C:\users\Administrator\Desktop\PowerShell Widgets
92 C:\users\Administrator\Desktop\Working
Description
-----------
This example shows Get-FolderItem taking pipeline input from Get-ChildItem and then saves
the output to $files. Group-Object is used with $Files to show the count of files in each
folder from where the command was executed.
.EXAMPLE
Get-FolderItem -Path $Pwd -MinAge 45
LastWriteTime : 4/25/2012 12:08:06 PM
FullName : C:\users\Administrator\Desktop\PowerShell Scripts\3_LevelDeep_ACL.ps1
Name : 3_LevelDeep_ACL.ps1
ParentFolder : C:\users\Administrator\Desktop\PowerShell Scripts
Length : 4958
LastWriteTime : 5/29/2012 6:30:18 PM
FullName : C:\users\Administrator\Desktop\PowerShell Scripts\AccountAdded.ps1
Name : AccountAdded.ps1
ParentFolder : C:\users\Administrator\Desktop\PowerShell Scripts
Length : 760
Description
-----------
Gets files that have a LastWriteTime of greater than 45 days.
.INPUTS
System.String
.OUTPUTS
System.IO.RobocopyDirectoryInfo
.NOTES
Name: Get-FolderItem
Author: Boe Prox
Date Created: 31 March 2013
Version History:
Version 1.5 - 09 Jan 2014
-Fixed bug in ExcludeFile parameter; would only work on one file exclusion and not multiple
-Allowed for better streaming of output by Invoke-Expression to call the command vs. invoking
a scriptblock and waiting for that to complete before display output.
Version 1.4 - 27 Dec 2013
-Added FullPathLength property
Version 1.3 - 08 Nov 2013
-Added ExcludeFile parameter
Version 1.2 - 29 July 2013
-Added Filter parameter for files
-Fixed bug with ParentFolder property
-Added default value for Path parameter
Version 1.1
-Added ability to calculate file hashes
Version 1.0
-Initial Creation
#>
[cmdletbinding(DefaultParameterSetName='Filter')]
Param (
[parameter(Position=0,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
[Alias('FullName')]
[string[]]$Path = $PWD,
[parameter(ParameterSetName='Filter')]
[string[]]$Filter = '*.*',
[parameter(ParameterSetName='Exclude')]
[string[]]$ExcludeFile,
[parameter()]
[int]$MaxAge,
[parameter()]
[int]$MinAge
)
Begin {
$params = New-Object System.Collections.Arraylist
$params.AddRange(@("/L","/S","/NJH","/BYTES","/FP","/NC","/NDL","/TS","/XJ","/R:0","/W:0"))
If ($PSBoundParameters['MaxAge']) {
$params.Add("/MaxAge:$MaxAge") | Out-Null
}
If ($PSBoundParameters['MinAge']) {
$params.Add("/MinAge:$MinAge") | Out-Null
}
}
Process {
ForEach ($item in $Path) {
Try {
$item = (Resolve-Path -LiteralPath $item -ErrorAction Stop).ProviderPath
If (-Not (Test-Path -LiteralPath $item -Type Container -ErrorAction Stop)) {
Write-Warning ("{0} is not a directory and will be skipped" -f $item)
Return
}
If ($PSBoundParameters['ExcludeFile']) {
$Script = "robocopy `"$item`" NULL $Filter $params /XF $($ExcludeFile -join ',')"
} Else {
$Script = "robocopy `"$item`" NULL $Filter $params"
}
Write-Verbose ("Scanning {0}" -f $item)
Invoke-Expression $Script | ForEach {
Try {
If ($_.Trim() -match "^(?<Size>\d+)\s(?<Date>\S+\s\S+)\s+(?<FullName>.*)") {
$object = New-Object PSObject -Property @{
ParentFolder = $matches.fullname -replace '(.*\\).*','$1'
FullName = $matches.FullName
Name = $matches.fullname -replace '.*\\(.*)','$1'
Length = [int64]$matches.Size
LastWriteTime = [datetime]$matches.Date
Extension = $matches.fullname -replace '.*\.(.*)','$1'
FullPathLength = [int] $matches.FullName.Length
}
$object.pstypenames.insert(0,'System.IO.RobocopyDirectoryInfo')
Write-Output $object
} Else {
Write-Verbose ("Not matched: {0}" -f $_)
}
} Catch {
Write-Warning ("{0}" -f $_.Exception.Message)
Return
}
}
} Catch {
Write-Warning ("{0}" -f $_.Exception.Message)
Return
}
}
}
}
#Save the file as a .PSM1 file first to use it as a module
function Get-SharePermissions{
<#
.SYNOPSIS
Retrieves share permissions.
.DESCRIPTION
Retrieves share permissions.
.PARAMETER computer
Name of server to test the port connection on.
.NOTES
Name: Get-SharePermissions
Author: Boe Prox
DateCreated: 12SEPT2010
.LINK
https://boeprox.wordpress.org
.EXAMPLE
Get-SharePermissions -computer Test
#>
[cmdletbinding(
DefaultParameterSetName = 'computer',
ConfirmImpact = 'low'
)]
Param(
[Parameter(
Mandatory = $True,
Position = 0,
ParameterSetName = 'computer',
ValueFromPipeline = $True)]
[array]$computer
)
Begin {
#Process Share report
$sharereport = @()
}
Process {
#Iterate through comptuers
ForEach ($c in $computer) {
Try {
Write-Verbose "Computer: $($c)"
#Retrieve share information from comptuer
$ShareSec = Get-WmiObject -Class Win32_LogicalShareSecuritySetting -ComputerName $c -ea stop
ForEach ($Shares in $sharesec) {
Write-Verbose "Share: $($Shares.name)"
#Try to get the security descriptor
$SecurityDescriptor = $ShareS.GetSecurityDescriptor()
#Iterate through each descriptor
ForEach ($DACL in $SecurityDescriptor.Descriptor.DACL) {
$arrshare = New-Object PSObject
$arrshare | Add-Member NoteProperty Computer $c
$arrshare | Add-Member NoteProperty Name $Shares.Name
$arrshare | Add-Member NoteProperty ID $DACL.Trustee.Name
#Convert the current output into something more readable
Switch ($DACL.AccessMask) {
2032127 {$AccessMask = "FullControl"}
1179785 {$AccessMask = "Read"}
1180063 {$AccessMask = "Read, Write"}
1179817 {$AccessMask = "ReadAndExecute"}
-1610612736 {$AccessMask = "ReadAndExecuteExtended"}
1245631 {$AccessMask = "ReadAndExecute, Modify, Write"}
1180095 {$AccessMask = "ReadAndExecute, Write"}
268435456 {$AccessMask = "FullControl (Sub Only)"}
default {$AccessMask = $DACL.AccessMask}
}
$arrshare | Add-Member NoteProperty AccessMask $AccessMask
#Convert the current output into something more readable
Switch ($DACL.AceType) {
0 {$AceType = "Allow"}
1 {$AceType = "Deny"}
2 {$AceType = "Audit"}
}
$arrshare | Add-Member NoteProperty AceType $AceType
#Add to existing array
$sharereport += $arrshare
}
}
}
#Catch any errors
Catch {
$arrshare | Add-Member NoteProperty Computer $c
$arrshare | Add-Member NoteProperty Name "NA"
$arrshare | Add-Member NoteProperty ID "NA"
$arrshare | Add-Member NoteProperty AccessMask "NA"
}
Finally {
#Add to existing array
$sharereport += $arrshare
}
}
}
End {
#Display report
$Sharereport
}
}
function Get-ShareNTFSPermissions{
<#
.SYNOPSIS
Retrieves NTFS permissions on a share.
.DESCRIPTION
Retrieves NTFS permissions on a share.
.PARAMETER computer
Name of server to test the port connection on.
.NOTES
Name: Get-SharePermissions
Author: Boe Prox
DateCreated: 12SEPT2010
.LINK
https://boeprox.wordpress.org
.EXAMPLE
Get-ShareNTFSPermissions -computer Test
#>
[cmdletbinding(
DefaultParameterSetName = 'computer',
ConfirmImpact = 'low'
)]
Param(
[Parameter(
Mandatory = $True,
Position = 0,
ParameterSetName = 'computer',
ValueFromPipeline = $True)]
[array]$computer
)
Begin {
#Process NTFS Share report
$ntfsreport = @()
}
Process {
#Iterate through each computer
ForEach ($c in $computer) {
Try {
Write-Verbose "Computer: $($c)"
#Gather share information
$shares = Gwmi -comp $c Win32_Share -ea stop | ? {$_.Name -ne 'ADMIN$'-AND $_.Name -ne 'C$' -AND $_.Name -ne 'IPC$'} | Select Name,Path
ForEach ($share in $shares) {
#Iterate through shares
Write-Verbose "Share: $($share.name)"
If ($share.path -ne "") {
#Retrieve ACL information from Share
$remoteshare = $share.path -replace ":","$"
Try {
#Gather NTFS security information from each share
$acls = Get-ACL "\\$computer\$remoteshare"
#iterate through each ACL
ForEach ($acl in $acls.access) {
If ($acl.FileSystemRights -match "\d") {
Switch ($acl.FileSystemRights) {
2032127 {$AccessMask = "FullControl"}
1179785 {$AccessMask = "Read"}
1180063 {$AccessMask = "Read, Write"}
1179817 {$AccessMask = "ReadAndExecute"}
-1610612736 {$AccessMask = "ReadAndExecuteExtended"}
1245631 {$AccessMask = "ReadAndExecute, Modify, Write"}
1180095 {$AccessMask = "ReadAndExecute, Write"}
268435456 {$AccessMask = "FullControl (Sub Only)"}
default {$AccessMask = "Unknown"}
}
}
Else {
$AccessMask = $acl.FileSystemRights
}
$arrntfs = New-Object PSObject
#Process NTFS Report
$arrntfs | Add-Member NoteProperty Computer $c
$arrntfs | Add-Member NoteProperty ShareName $Share.name
$arrntfs | Add-Member NoteProperty Path $share.path
$arrntfs | Add-Member NoteProperty NTFS_User $acl.IdentityReference
$arrntfs | Add-Member NoteProperty NTFS_Rights $AccessMask
}
}
Catch {
$arrntfs = New-Object PSObject
#Process NTFS Report
$arrntfs | Add-Member NoteProperty Computer $c
$arrntfs | Add-Member NoteProperty ShareName "NA"
$arrntfs | Add-Member NoteProperty Path "NA"
$arrntfs | Add-Member NoteProperty NTFS_User "NA"
$arrntfs | Add-Member NoteProperty NTFS_Rights "NA"
}
Finally {
#Add to existing array
$ntfsreport += $arrntfs
}
}
}
}
Catch {
$arrntfs | Add-Member NoteProperty Computer $c
$arrntfs | Add-Member NoteProperty ShareName "NA"
$arrntfs | Add-Member NoteProperty Path "NA"
$arrntfs | Add-Member NoteProperty NTFS_User "NA"
$arrntfs | Add-Member NoteProperty NTFS_Rights "NA"
}
Finally {
#Add to existing array
$ntfsreport += $arrntfs
}
}
}
End {
#Display report
$ntfsreport
}
}
#Rename files or folders to lowercase letters
Get-ChildItem -Path "C:\Users\khaleesi\*.txt" -Recurse | % { if ($_.Name -cne $_.Name.ToLower()) { ren $_.FullName $_.Name.ToLower() } }
#Backup with Robocopy and powershell by Mario Cortes
Write-host -foregroundcolor 'green' "Robocopy&PowerShell by Mario Cortes";
$arSourceFolders = ("D:\MySourcePath1", "D:\MySourcePath2");
$arDestinationFolders = ("F:\MyDestinationPath1", "F:\MyDestinationPath2");
if($arSourceFolders.Length -ne $arDestinationFolders.Length)
{
Write-host -foregroundcolor 'red' "The numbers of folders have to similar";
}
else{
for($i=0; $i -lt $arSourceFolders.Length; $i++)
{
Write-host -foregroundcolor 'green' "Process " $arSourceFolders[$i] " -> " $arDestinationFolders[$i] ;
robocopy $arSourceFolders[$i] $arDestinationFolders[$i] /COPYALL /E /R:0 /xo
}
}
Write-host -foregroundcolor 'green' "Done :)";
#Enter the path where you need to set the permissions
$Path="D:\Test"
#Get the current permissions of the folder
$ACL=Get-Acl -Path $Path
#Create a new access rule system object with permission rules. #Winterfell is the AD Domain and jsnow is the AD User, just in case you were wondering
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("winterfell\jsnow", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
#Create ACL Rule
$Acl.SetAccessRule($Ar)
#Set the permissions
Set-ACL -Path $Path -AclObject $ACL
#Assign ownership to BUILTIN\Administrators
takeown.exe /A /F $Path
#For Windows Server 2012
#Made a quick script for adding ransomware extensions and know files to the file screen file groups. This is so you can easily keep multiple file servers with FSRM in sync and make updates in one file pushed out to multiple servers.
#Use the New-FSRMFileGroup cmdlet for new file groups
#https://technet.microsoft.com/en-us/library/jj900600(v=wps.630).aspx
#UseSet-FSRMFileGroup for updating existing file groups
#https://technet.microsoft.com/en-us/library/jj900615(v=wps.630).aspx
Set-FsrmFileGroup -Name "<Enter File Group Name here>" -IncludePattern @("*!recover!*.*", "*+recover+*.*", "*-recover-*.*", "*.0x0", "*.1999", "*.73i87A", "*.AES256", "*.CTB2", "*.CrySiS", "*.CryptoTorLocker2015!", "*.EnCiPhErEd", "*.Encrypted", "*.KEYHOLES", "*.KEYZ", "*.LOL!", "*.LeChiffre", "*.OMG!", "*.PoAr2w", "*.R4A", "*.R5A", "*.RADAMANT", "*.RDM", "*.RRK", "*.SUPERCRYPT", "*.XRNT", "*.aaa", "*.abc", "*.better_call_saul", "*.bleep", "*.bloc", "*.btc", "*.btc-help-you", "*.btcbtcbtc", "*.cbf", "*.cerber", "*.chifrator@qq_com", "*.clf", "*.code", "*.coverton", "*.crime", "*.crinf", "*.crjoker", "*.cry", "*.crypt", "*.crypted", "*.crypto", "*.cryptotorlocker*", "*.ctbl", "*.czvxce", "*.darkness", "*.dyatel@qq_com", "*.ecc", "*.enc", "*.encedRSA", "*.encrypt", "*.encryptedAES", "*.encryptedRSA", "*.encryptedped", "*.enigma", "*.exx", "*.ezz", "*.frtrss", "*.fucked", "*.fun", "*.good", "*.gruzin@qq_com", "*.gws", "*.ha3", "*.hb15", "*.helpdecrypt@ukr_net", "*.hydracrypt_ID*", "*.infected", "*.justbtcwillhelpyou", "*.keybtc@inbox_com", "*.kimcilware", "*.kkk", "*.korrektor", "*.kraken", "*.lock", "*.lock*", "*.locked", "*.locky", "*.magic", "*.micro", "*.nalog@qq_com", "*.nochance", "*.one-we_can-help_you", "*.oor", "*.oplata@qq_com", "*.oshit", "*.p5tkjw", "*.pizda@qq_com", "*.relock@qq_com", "*.remind", "*.rokku", "*.ryp", "*.sanction", "*.scl", "*.sport", "*.surprise", "*.toxcrypt", "*.troyancoder@qq_com", "*.trun", "*.ttt", "*.vault", "*.vscrypt", "*.vvv", "*.xort", "*.xrtn", "*.xtbl", "*.xxx", "*.xyz", "*.zzz", "*.{CRYPTENDBLACKDC}", "*DECRYPT_INSTRUCTION*", "*_Locky_recover_instructions*", "*_crypt*", "*_help_instruct*.*", "*_recover_*.*", "*_secret_code*", "*decrypt my file*.*", "*decryptmyfiles*.*", "*files_are_encrypted.*", "*gmail*.crypt", "*rec0ver*.*", "*recover_instruction*.*", "*recover}-*.*", "*restore_fi*.*", "*want your files back.*", "*warning-!!*.*", "Coin.Locker.txt", "DECRYPT_ReadMe*", "DecryptAllFiles*", "YOUR_FILES.HTML", "_help_instruct*.*", "_how_recover*", "confirmation.key", "cryptolocker.*", "de_crypt_readme.*", "decrypt-instruct*.*", "decrypt_instruct*.*", "enc_files*", "enc_files.txt", "encryptor_raas_readme_liesmich*", "help_decrypt*.*", "help_decrypt_your_files*", "help_file_*.*", "help_instructions.*", "help_recover*.*", "help_restore*.*", "help_your_file*.*", "how to decrypt*.*", "how_recover*.*", "how_to_decrypt*.*", "how_to_recover*.*", "howto_restore*.*", "howtodecrypt*.*", "install_tor*.*", "last_chance.txt", "message.txt", "readme_decrypt*.*", "readme_for_decrypt*.*", "recovery+*.*", "recovery_file.txt", "recovery_key.txt", "vault.hta", "vault.key", "vault.txt", "your_files.url")
#Path to Check
$Path="C:\Temp\Test"
#Check if Path exists
If (!(Test-Path $Path))
{
#Create if it doesn't
New-Item -Path $Path -ItemType Directory -Force
}
#One method is to call the .net library
#Function RandomPW {
#[Reflection.Assembly]::LoadWithPartialName(“System.Web”)
#[System.Web.Security.Membership]::GeneratePassword(20,10) | gm | FT}
#This is another mehtod to get the pw from an random pw generator site
#$initialPW = $(Invoke-RestMethod https://www.random.org/passwords/?num=1"&"len=20"&"format=plain"&"rnd=new) -replace "`n"
#The following function is the best I found fo far
function Get-RandomPassword($length)
{
$length-=1
$lower = 'abcdefghijklmnopqrstuvwxyz'
$upper = $lower.ToUpper()
$number = 0..9
$special='~!@#$%^&*()_+|}{[]\'
$chars = "$lower$special$upper".ToCharArray()
$pass = Get-Random -InputObject $chars -Count $length
$digit = Get-Random -InputObject $number
(-join $pass).insert((Get-Random $length),$digit)
}
#example
Get-RandomPassword -Length 20
#example if you want multiple passwords
1..20 | % {Get-RandomPassword -Length 20}
#Here is a quick and dirty way to remove all user defined variables.
#Helpful when you want to restart the script from scratch and don't want any existing values
$ScriptContent = Get-Content "C:\Users\JohnCena\Bodypump.ps1"
$SplitContent = $ScriptContent -split '[^\w$]'
$Variables = $SplitContent | ? {$_ -like "$*"} | Sort-Object | Get-unique
$Variables
# remove some variables
Get-Variable * -Scope global | &{process{
if (!$_.Description -and !$_.Option -and !$_.Attributes) {
Remove-Variable $_.Name -Scope global -ErrorAction SilentlyContinue
}
}}
# up to you
$Error.Clear()
# SearchGPOsForSetting.ps1
#
# http://blogs.technet.com/b/grouppolicy/archive/2009/04/14/tool-images.aspx
# http://blogs.technet.com/b/grouppolicy/archive/2009/04/17/find-settings-in-every-gpo.aspx
#
# Powershell script that does the following:
# SearchGPOsForSetting.ps1 [–IsComputerConfiguration] <boolean> [-Extension] <string>
# [-Where] </string><string> [-Is] </string><string> [[-Return] </string><string>] [[-DomainName] </string><string>]
# [-Verbose] [-Debug] [-ErrorAction <actionpreference>] [-WarningAction </actionpreference><actionpreference>]
# [-ErrorVariable <string>] [-WarningVariable </string><string>] [-OutVariable </string><string>] [-OutBuffer <int32>]
#
# Example: .\SearchGPOsForSetting.ps1 -IsComputerConfiguration $true -Extension Security -Where Name -Is LockoutDuration -Return SettingNumber
# Example: .\SearchGPOsForSetting.ps1 -IsComputerConfiguration $true -Extension Registry -Where Name -Is ACSettingIndex -Return SettingNumber
# Example: .\SearchGPOsForSetting.ps1 -IsComputerConfiguration $true -Extension SoftwareInstallation -where AutoInstall -is true -Return Path
# Example: .\SearchGPOsForSetting.ps1 -IsComputerConfiguration $true -Extension Registry -where Name -is "Run these programs at user logon" -Return State
param (
[Parameter(Mandatory=$true)]
[Boolean] $IsComputerConfiguration,
[Parameter(Mandatory=$true)]
[string] $Extension,
[Parameter(Mandatory=$true)]
[string] $Where,
[Parameter(Mandatory=$true)]
[string] $Is,
[Parameter(Mandatory=$false)]
[string] $Return,
[Parameter(Mandatory=$false)]
[string] $DomainName = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
)
function print
{
param
(
$displayName,
$value
)
$host.UI.WriteLine();
$stringToPrint = "The Gpo '" + $displayName + "' has a " + $Extension + " setting where '" + $Where + "' is equal to '" + $Is + "'";
if ($Return -ne $null)
{
$stringToPrint += " and the value of its '" + $Return + "' property is: '" + $value + "'";
}
$host.UI.Write([ConsoleColor]::Magenta, [ConsoleColor]::Black, $stringToPrint);
$host.UI.WriteLine();
}
function processNodes
{
param
(
$nodes,
$foundWhere
)
$thePropertyWeWant = $Where;
# If we already found the $Where then we are looking for our $Return value now.
if ($foundWhere)
{
$thePropertyWeWant = $Return;
}
foreach($node in $nodes)
{
$valueWeFound = $null;
#Here we are checking siblings
$lookingFor = Get-Member -InputObject $node -Name $thePropertyWeWant;
if ($lookingFor -ne $null)
{
$valueWeFound = $node.($lookingFor.Name);
}
else #Here we are checking attributes.
{
if ($node.Attributes -ne $null)
{
$lookingFor = $node.Attributes.GetNamedItem($thePropertyWeWant);
if( $lookingFor -ne $null)
{
$valueWeFound = $lookingFor;
}
}
}
if( $lookingFor -ne $null)
{
#If we haven't found the $Where yet, then we may have found it now.
if (! $foundWhere)
{
# We have found the $Where if it has the value we want.
if ( [String]::Compare($valueWeFound, $Is, $true) -eq 0 )
{
# Ok it has the value we want too. Now, are we looking for a specific
# sibling or child of this node or are we done here?
if ($Return -eq $null)
{
#we are done, there is no $Return to look for
print -displayName $Gpo.DisplayName -value $null;
return;
}
else
{
# Now lets look for $Return in the siblings and then if no go, the children.
processNodes -nodes $node -foundWhere $true;
}
}
}
else
{
#we are done. We already found the $Where, and now we have found the $Return.
print -displayName $Gpo.DisplayName -value $valueWeFound;
return;
}
}
if (! [String]::IsNullOrEmpty($node.InnerXml))
{
processNodes -nodes $node.ChildNodes -foundWhere $foundWhere;
}
}
}
#Import our module for the call to the Get-GPO cmdlet
Import-Module GroupPolicy;
$allGposInDomain = Get-GPO -All -Domain $DomainName;
$xmlnsGpSettings = "http://www.microsoft.com/GroupPolicy/Settings";
$xmlnsSchemaInstance = "http://www.w3.org/2001/XMLSchema-instance";
$xmlnsSchema = "http://www.w3.org/2001/XMLSchema";
$QueryString = "gp:";
if($IsComputerConfiguration){ $QueryString += "Computer/gp:ExtensionData/gp:Extension"; }
else{ $QueryString += "User/gp:ExtensionData/gp:Extension"; }
foreach ($Gpo in $allGposInDomain)
{
$xmlDoc = [xml] (Get-GPOReport -Guid $Gpo.Id -ReportType xml -Domain $Gpo.DomainName);
$xmlNameSpaceMgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable);
$xmlNameSpaceMgr.AddNamespace("", $xmlnsGpSettings);
$xmlNameSpaceMgr.AddNamespace("gp", $xmlnsGpSettings);
$xmlNameSpaceMgr.AddNamespace("xsi", $xmlnsSchemaInstance);
$xmlNameSpaceMgr.AddNamespace("xsd", $xmlnsSchema);
$extensionNodes = $xmlDoc.DocumentElement.SelectNodes($QueryString, $XmlNameSpaceMgr);
foreach ($extensionNode in $extensionNodes)
{
if ([String]::Compare(($extensionNode.Attributes.Item(0)).Value,
"http://www.microsoft.com/GroupPolicy/Settings/" + $Extension, $true) -eq 0)
{
# We have found the Extension we are looking for now recursively search
# for $Where (the property we are looking for a specific value of).
processNodes -nodes $extensionNode.ChildNodes -foundWhere $false;
}
}
}
(get-item "HKLM:\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters").GetValue("HostName")
# Load Active Directory Module
if(@(get-module | where-object {$_.Name -eq "ActiveDirectory"} ).count -eq 0) {import-module ActiveDirectory}
@msm-fc
Copy link

msm-fc commented Jul 19, 2019

https://gist.github.com/frndlyy/e7e51d3acddee51c4e42d0ee9bbe0dc0#file-ad_group_clear_members-ps1

WATCH OUT!

line 14 scope as written is all domain groups. Thankfully there's an error in this line as well or someone might be having a bad day.

To remove all members from a group it's:

Set-ADGroup -Clear member

But under no circumstances would you ever want to pipe Get-ADGroup unfiltered and without a limited searchbase into that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment