Thursday, December 31, 2015

Optimising AD query results.


Limiting results to queries on the active directory (AD) is often important because the results can often be relatively large sets of data and you may only need examples of the type of objects you are querying.  Restricting results to the first 10 is often useful.

| Select -first 10

The querying method can also be optimised by correctly using filter and where conditions.

In a nutshell this paragraph from the post on the link below explains why.

"The –Filter and –LdapFilter parameters cause filtering to take place on the remote computer, thus reducing the amount of information that gets returned across the network to your computer. By contrast, Where-Object causes filtering to take place on your computer, which means that all the information about all your users must be returned to your machine."


http://blogs.technet.com/b/csps/archive/2010/06/06/reffilterwhere.aspx

Tuesday, December 22, 2015

Calling ICACLS.exe from powershell


Although Get-Acl and Set-Acl are available in Powershell you may still prefer to call ICACLS.EXE

This is a folder permissioning example:

$target = $env:SystemDrive + "\Apps\Folder"
$perms = "domainname\Group:(OI)(CI)(F)"
& icacls.exe ($target) /grant ($perms)



Also see this useful post http://tomandersonpro.net/ntfs-permissions-with-powershell/

and this useless page about ICACLS.EXE
https://technet.microsoft.com/en-us/library/cc753525.aspx

Note on the above
CI = container inherit which means it will apply to "This folder and subfolders"
OI = object inherit which means it will apply to "This folder, subfolders and files"

Monday, December 21, 2015

Environmental Variables


Environmental variables (EV) have powershell variables automatically assigned to them.

E.g.

The EV  ALLUSERPROFILE also has a powershell variable $env:ALLUSERPROFILE  and so on.




To set or update a machine environmental variable

[Environment]::SetEnvironmentVariable("TestVariableName", "My Value", "Machine")

Tuesday, December 8, 2015

Check your version


Certain Cmdlets may not be available in earlier versions of Powershell
To check your version of powershell, at the powershell prompt type

Get-Host

or

$PSVersionTable.PSVersion

 

Download Powershell 4.0
https://www.microsoft.com/en-us/download/details.aspx?id=40855

Download Powershell 5.0 
Latest version at the time of writing
https://www.microsoft.com/en-us/download/details.aspx?id=50395

Monday, November 16, 2015

List recursive group memberships


This script prompts for the username and returns a recursive list of the users group memberships.  It uses the Object Identifier (OID) 1.2.840.113556.1.4.1941 to call the extensible match matching rule LDAP_MATCHING_RULE_IN_CHAIN.  See the links below for further information on how this query operates.

http://ldapwiki.willeke.com/wiki/1.2.840.113556.1.4.1941

https://msdn.microsoft.com/en-us/library/aa746475%28v=vs.85%29.aspx


param (
    [Parameter (ValueFromPipeline=$true, Mandatory=$true)]
    [string]$username = $null
       )

$dn = (Get-ADUser $username).DistinguishedName
Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn) | select -expand Name | sort name



replace sort name with measure to return the number of groups.  This script can be modified to apply to machine names by the use of the Get-ADComputer cmdlet

Consider expanding this to compare recursive group memberships of two users.

The above is also an example of an argument/parameter prompt.  To produces multiple prompts for augments to turn in to variables try 

param (
    [Parameter (ValueFromPipeline=$true, Mandatory=$true)]
    [string]$username = $null,
    [Parameter (ValueFromPipeline=$true, Mandatory=$true)]
    [string]$PartialGroupName = $null

     
)

Sunday, November 15, 2015

Get-ADObject with an LDAPfilter


Powershell command to determine the contents matching membership of 2 groups and fitting a specified pattern. The output is then controlled using the format table cmdlet. Out-File can be used the write the output to a file.

Get-ADObject -LDAPFilter "(&(memberOf=cn=GROUPNAME1,ou=Live,ou=Applications,ou=Groups,dc=dom1st,dc=dom2nd,dc=local)(memberOf=cn=GROUPNAME2,ou=Live,ou=Applications,ou=Groups,dc=dom1st,dc=dom2nd,dc=local))" | where {$_.name -like "DW*"} | Format-Table Name


This is a similar command which lists the groups which both users are a member of i.e. common groups.  It is not recursive.

get-adobject -LDAPFilter "(&(member=CN=User1,OU=TestAccounts,OU=GenericAccounts,OU=Users,OU=firm,DC=DC1,DC=DC2,DC=local)(member=CN=user2,OU=LU,OU=Users,OU=firm,DC=DC1,DC=DC2,DC=local))"


To list uncommon group place the NOT operator just inside the bracket of the second condition, just before "member" in this case.

LDAP Query basics
https://technet.microsoft.com/en-us/library/aa996205%28v=exchg.65%29.aspx (broke)

https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx

Building on the first query above this script obtains the users which are in both groups and then removes the resulting user accounts from a specified group.... script to be added..... 

Script to copy user accounts from one group to another

# Powershell Script to COPY AD User accounts from one group to another

# Usage Launch a powershell command window in a user context with permissions to the change the AD
# .\<path>\CopyUsersToUpdateAppGroup.ps1 <OldGroupName> <NewGroupName>


$split = $args.split(" ")
$OldGroupName = $split[0]
$NewGroupName = $split[1]
$Domain = "FQDN of AD Domain Goes Here"

$UserNames = Get-ADGroupMember $OldGroupName  | Get-ADUser | Select-Object `
-ExpandProperty SamAccountName

# Add each user to the newly created AD group
ForEach ($UserName in $UserNames) {
echo $User
$User = [ADSI]("WinNT://$Domain/$UserName")
$Grp = [ADSI]("WinNT://$Domain/$NewGroupName")
$Grp.PSBase.Invoke("Add",$User.PSBase.Path)
}


Outputing to a variable and text file

Outputing to a text file which is written to the root of the current userprofile.

get-appvclientconfiguration -outvariable vname 
$vname | Out-File vname.txt


Out-File is often useful but is usually quite frustrating without the -width x parameter added.  By default it restricts the width of the outputed lines to the same as the console which is 80 characters in a default console window.  The result is that lines are truncated with ... added where they are longer.  Override the problem but setting a larger width value.

Get-WMIObject - WMI query example


Powershell command to retrieve the productcode guids of the installed MSIs

Get-WmiObject -Namespace root\ccm\CIModels -Class CCM_MSIProduct | Sort-Object ProductName |Format-Table ProductName,ProductCode,ProductVersion -auto


Use this tool to browser the WMI items to query

http://www.microsoft.com/en-us/download/details.aspx?id=8572

Get-ADPrincipleGroupMembership - lists the groups that a user, computer or group is a member of.



While this command can be used to obtain the list of groups a user  or a group is a member of, it will not do recursion i.e. it will not list the groups a user is in as a result of groups.

Get-ADPrincipalGroupMembership -Identity <userORgroupORComputer> | Select-Object -ExpandProperty SamAccountName | Sort-Object SamAccountName

in the above command place a where filter before select object cmdlet to narrow the results. 

https://technet.microsoft.com/en-us/library/ee617259.aspx 

This script removes an account from all groups with a name matching a string.  Note that the confirmation has been knocked out! Be careful.

 $AccountDN = "CN=MACHINENAME,OU=xxx,OU=xxx,OU=xxx,OU=xxx,OU=XXX,DC=xxx,DC=xxx,DC=xxx"
$grouplist = Get-ADPrincipalGroupMembership -id $AccountDN | where {$_.name -like "*string*"} | select -expand name

echo $grouplist

$ConfirmPreference = "none"

ForEach ($group in $grouplist)

{
echo $group
Remove-ADPrincipalGroupMembership -id $AccountDN -MemberOf $group
}

Get-ADComputer - list and return the computers matching the query


Command to obtain the list of computers in a specified AD OU - could be done with Get-ADUser as well probably.

Get-ADComputer -filter * -SearchBase "OU=Live,OU=Laptops,OU=Physical,OU=Desktops,OU=1,DC=name2,DC=name1,DC=local" | select name | sort name

In the above command if you replace the sort name with measure the output will count the total number of items and return that as the count.

Get-ADGroupMember - lists machines or user members of groups


Commands to output the members of a group

Get-ADGroupMember -Id <GroupName> | Export-CSV c:\temp\GroupOutput.CSV -NoTypeInformation 

this one uses the -recursive switch which lists the members of groups within the group.  Note the use of multiple -notlike items

Get-ADGroupMember -Identity <GroupName> -recursive | Select name | sort name | where {$_.name -notlike "MACH*" -and $_.name -notlike "VW*"}

Command Lines


Command lines:
powershell
-file "filename.ps1" (specifiies which script file to run)
-NonInteractive (prevents output to the command window)
-executionpolicy bypass -file "filename.ps1"  (enables script files to execute when the execution policy is restricted)

 C:\Windows\System32\WindowsPowerShell\v1.0 is added to the system path when powershell is installed.  Any custom scripts that you write can be placed in this location and easily called from a powershell command prompt.

Cmdlet reference and tutorial pages

References

Powershell 5.0 is the current version at the time up update December 2015.  These links refer to the version 5.0 release unless shown. 

Technet Library Scripting with Windows Powershell
https://technet.microsoft.com/en-us/library/bb978526.aspx

Technet Archive Windows Powershell 1.0 Basic Cmdlets
https://technet.microsoft.com/en-us/library/hh848794.aspx

Technet Library Windows Powershell 5.0 Modules and Cmdlets
https://technet.microsoft.com/en-us/library/hh847741.aspx

AD Cmdlets
https://technet.microsoft.com/en-us/library/ee617195.aspx

Managing App-V 5.0
https://technet.microsoft.com/en-us/library/jj713419.aspx

Text Manipulation
http://newdelhipowershellusergroup.blogspot.co.uk/p/tutorial-series.html

Special Characters and Tokens
http://www.neolisk.com/techblog/powershell-specialcharactersandtokens

Tutorials
https://www.simple-talk.com/sysadmin/powershell/powershell-one-liners--accessing,-handling-and-writing-data-/

https://www.simple-talk.com/sysadmin/powershell/powershell-one-liners--collections,-hashtables,-arrays-and-strings/

http://www.howtogeek.com/137803/geek-school-learn-how-to-automate-windows-with-powershell/

http://www.computerperformance.co.uk/powershell/

Filter Types



Filter Types - cmdlets may not support all of these

-lt -- Less than
-le -- Less than or equal to
-gt -- Greater than
-ge -- Greater than or equal to
-eq -- Equal to
-ne -- Not equal to
-like - Like; uses wildcards for pattern matching
-notlike -- Equal to
-clike -- case sensative like
-approx -- ?
-bor -- ?
-band -- ?
-recursivematch -- ?

http://www.itprotoday.com/management-mobility/powershell-basics-filtering-objects

LDAP Query Operators

= equal
! not
& and
| or
* wildcard

more here
http://windowsitpro.com/powershell/windows-powershell-operators

Thursday, November 12, 2015

Get-ADGroup queries the AD for group object items eg names


Get-ADGroup

Command to obtain group names containing 2 specified strings which is then further filtered for the case sensitive instances by the where cmdlet using the -clike operator, the case sensitive version of -like in the where cmdlet.

Get-ADGroup -filter {Name -like "*string1*" -and Name -like "*STrIng2*"} | where {$_.name -clike "*STrIng2*"} | Select-Object name | Sort-Object name

Notes
where is short for Where-Object
Select-Object and Sort-Object can be shortened to Select and Sort
-notlike is also a valid operator for the where object.

This command is useful to include the group description in the output

 get-adgroup -filter {name -like "*mystring*"} -Properties description | select name,description