Giter Site home page Giter Site logo

lazywinadmin / adsips Goto Github PK

View Code? Open in Web Editor NEW
193.0 23.0 47.0 769 KB

PowerShell module to interact with Active Directory using ADSI and the System.DirectoryServices namespace (.NET Framework)

Home Page: http://www.lazywinadmin.com

License: MIT License

PowerShell 100.00%
powershell activedirectory adsi directoryservices active-directory scripting directoryservices-namespace hacktoberfest

adsips's Introduction

AdsiPS

Build Status

AdsiPS is a PowerShell module to interact with Active Directory using the .NET Framework (ADSI, System.DirectoryServices namespace,...)

Note: This module currently only works on Windows Operating Systems.

Usage

Option A: Download from PowerShell Gallery

Only from PowerShell v5.1 (on Windows OS only)

Install-Module -name ADSIPS

Option B: Manual download from GitHub

  1. Download the repository
  2. Unblock the zip file
  3. Extract the folder to a module path (e.g. $home\Documents\WindowsPowerShell\Modules)
  4. Run build.ps1 (exists in project root).
    • NOTE: If you get an error after running build.ps1 - please use build.ps1 -InstallDependencies
  5. build.ps1 creates a folder called ~\buildoutput\AdsiPs in the directory which AdsiPs was saved to
  6. Inside of \buildoutput\AdsiPs there is a file called AdsiPs.psm1
  7. Run Import-Module -Path "C:\Path\To\buildoutput\AdsiPs\AdsiPs.psm1" to import the AdsiPs module

Documentation

Thanks to all our Contributors!

  • @LazyWinAdmin
  • @MickyBalladelli
  • @christophekumor
  • @omiossec
  • @oze4
  • @andrewtchilds
  • @NicolasBn
  • @gerane
  • @Skoetting
  • @LaurentLienhard
  • @JM2K69

Resources

adsips's People

Contributors

andrewtchilds avatar christophekumor avatar gerane avatar jm2k69 avatar laurentlienhard avatar lazywinadmin avatar nicolasbn avatar omiossec avatar oze4 avatar simonkoetting avatar skoetting avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adsips's Issues

ValueFromPipelineByPropertyName in Disable-ADSIComputer

From what I understand (this is the first I've seen someone do this):

[parameter(Mandatory = $true, ValueFromPipelineByPropertyName = "SamAccountName", ValueFromPipeline = $true)]

ValueFromPipelineByPropertyName takes a bool as its value. I took a look at MSDN and it would appear that proper values are indeed $true or $false.

Or am I wrong and missing someting?

Support to retrieve ReadOnly and Writtable Domain Controllers

We should look at implementing this into the module.
Get-ADDomainController provides a property called isReadOnly.

See (Thanks @MickyBalladelli ):

This info is also available using nltest /dsgetdc /writtable
Queries the DNS server for a list of domain controllers and their corresponding IP addresses

Thanks @NicolasBn

Adopt PSTypeNames

This will allow:

  • more Pipeline usage
  • scenario like Get-ADSISchema -ForestName (Get-ADSIForest)
  • ...

Consider alternative or replacement to ambiguous name resolution

Hiyo!

Was looking to use this module for a small bit, but ran into issues with the anr queries in group membership functions (example).

Not sure what the best option would be, but as far as I can tell, there's no way to disambiguate an anr query. For example, let's say I have a user wf. I also have various other users, wframe, wfranklin, and so forth. I can't see a way to work with wf effectively ((anr=wf) returns all matching wf* AFAICT).

Potential options:

  • ParameterSet (or something along those lines) for MemberQuery
  • Constructed filter that checks samaccountname, userprincipalname, distinguishedname (more or less identity props as desired) for the Member value
  • Something else?

Cheers!

Get-ADSIUser LimitSize

Get-ADSIUser default result size is 1000, add a parameter for SizeLimit for each case

Group Policy Objects

Is there anyway to retrieve Group policy objects, Links, permissions, using .NET ?

I already have some basic code here Get-ADSIGroupPolicyObject but it is far from perfect.

I would like to have the same approach as Get-ADSIUser, that I'm reusing in Remove-ADSIUser, Unlock-ADSIUser, Enable-ADSIUSer, Disable-ADSIUser

Remove-ADSIGroupMember add return result

When using Remove-ADSIGroupMember there is no difference between a user existing in a group and a user not in the group.

Perhaps using the return of $group.members.remove($Member) can help to say if the user was really removed or if the command did nothing .

Get-ADSIComputer -Identity $Computer does not like multiple computers with same name

PSMessageDetails : Exception : System.Management.Automation.MethodInvocationException: Exception calling "FindByIdentity" with "2" argument(s): "Multiple principals contain a matching Identity." ---> System.DirectoryServices.AccountManagement.MultipleMatchesException: Multiple principals contain a matching Identity. at System.DirectoryServices.AccountManagement.ADStoreCtx.FindPrincipalByIdentRefHelper(Type principalType, String urnScheme, String urnValue, DateTime referenceDate, Boolean useSidHistory) at System.DirectoryServices.AccountManagement.ADStoreCtx.FindPrincipalByIdentRef(Type principalType, String urnScheme, String urnValue, DateTime referenceDate) at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable1 identityType, String identityValue, DateTime refDate)
at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, String identityValue)
at System.DirectoryServices.AccountManagement.ComputerPrincipal.FindByIdentity(PrincipalContext context, String identityValue)
at CallSite.Target(Closure , CallSite , Type , Object , String )
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction2.Run(InterpretedFrame frame) at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame) at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame) TargetObject : CategoryInfo : NotSpecified: (:) [], MethodInvocationException FullyQualifiedErrorId : MultipleMatchesException ErrorDetails : InvocationInfo : System.Management.Automation.InvocationInfo ScriptStackTrace : at Get-ADSIComputer<Process>, <No file>: line 200 at <ScriptBlock>, <No file>: line 219 PipelineIterationInfo : {}

Performance - Using PropertiesToLoad

Look at implementing PropertiesToLoad on classes such as:

  • System.DirectoryServices.AccountManagement.GroupPrincipal
  • System.DirectoryServices.AccountManagement.UserPrincipal
  • System.DirectoryServices.AccountManagement.ComputerPrincipal

The default set of properties retrieve from AD for each object is around 25 properties. Might want to limit that.

Get-ADSIPrincipalGroupMembership Problem since Last update

Since a part of the function was removed in the last update, there is now missing group in the result.

#Actual function
PS C:\Windows\system32> Get-ADSIPrincipalGroupMembership -Identity UserTest

name                                                               description                                                       
----                                                               -----------                                                       
Group Policy Creator Owners                                        Members in this group can modify group policy for the domain      
Domain Admins                                                      Designated administrators of the domain                           
Administrators                                                     Administrators have complete and unrestricted access to the com...


#My function version
PS C:\Windows\system32> Get-ADSIPrincipalGroupMembership2 -Identity UserTest

name                                                               description                                                       
----                                                               -----------                                                       
Domain Users                                                       All domain users                                                  
Group Policy Creator Owners                                        Members in this group can modify group policy for the domain      
Domain Admins                                                      Designated administrators of the domain                           
Administrators  

you have the same result as my function if you use the AD Module function :

PS C:\Windows\system32> Get-ADPrincipalGroupMembership -Identity UserTest | select name

name                                                                                                                                 
----                                                                                                                                 
Domain Users                                                                                                                         
Administrators                                                                                                                       
Domain Admins                                                                                                                        
Group Policy Creator Owners 

Assumptive Nature - New-ADSIDirectoryContext

This is more of a suggestion that an issue.

I suggest removing the assumptive nature of the Forest and Domain Parameters using :

	[Parameter(ParameterSetName = 'Domain')]
	$DomainName = [System.DirectoryServices.ActiveDirectory.Domain]::Getcurrentdomain(),
	
	[Parameter(ParameterSetName = 'Forest')]
	$ForestName = [System.DirectoryServices.ActiveDirectory.Forest]::Getcurrentforest(),

This caused an issue when I was running the commands from a non-domain joined system. Even when I was providing the Parameters with my own values they would still fail - The only fix I was able to come up with was removing these default values.

$DirectoryEntryParams = $ContextSplatting.remove('ContextType') will return null.

When creating Directory Enties using New-ADSIDirectoryEntry, the $DirectoryEntryParams splat is being set to null inadvertently.

$ContextSplatting.remove('ContextType') has no output, it only removes the ContextType from the object, so when running the below code, it just sets $DirectoryEntryParams to null.

$DirectoryEntryParams = $ContextSplatting.remove('ContextType')
$DirectoryEntry = New-ADSIDirectoryEntry @DirectoryEntryParams

If you do something like the following, it will properly create the Directory Entry. Currently, functions using the above method will never run under a different context.

$DirectoryEntryParams = $ContextSplatting
$DirectoryEntryParams.remove('ContextType')
$DirectoryEntry = New-ADSIDirectoryEntry @DirectoryEntryParams

To replicate you can try running Get-ADSIUser -LDAPFilter -Credential with some incorrect credentials. The command will not run as the credentials supplied.

I should have a pull request coming here shortly to fix this.

Add Pester tests for each cmdlet

I have noticed that this module lives without pester tests.
This makes refactoring pretty difficult.

I would like to start with this issue, the process add pester tests to this module, which we could track here.

Get-ADSIComputer $ComputerName

When using Get-ADSIComputer $ComputerName

I'm getting the following error

Get-AdsiComputer $env:COMPUTERNAME
Get-ADSIComputer : A positional parameter cannot be found that accepts argument ''.
At line:1 char:1

  • Get-AdsiComputer $env:COMPUTERNAME
  •   + CategoryInfo          : InvalidArgument: (:) [Get-ADSIComputer], ParameterBindingException
      + FullyQualifiedErrorId : PositionalParameterNotFound,Get-ADSIComputer
    

Support for ACL

Access can be retrieve using something like:
([ADSI]"LDAP://").psbase.ObjectSecurity.Access

Maybe having two new cmdlets, something like:

  • Set-AdsiAcl
  • Get-AdsiAcl

New-ADSIDirectoryEntry was ignoring Path if Credentials weren't provided

If Credentials weren't provided, New-ADSIDirectoryEntry would ignore $Path and always use the default. $Path is only added to ArgumentList if PSBoundParameters contains Credential

If ($PSBoundParameters['Credential'])
{
    $ArgumentList = $Path, $($Credential.UserName), $($Credential.GetNetworkCredential().password)
}

Performance - Recommended approach when query AD

If you take a look at the functions from this module, you'll see that I mostly use the namespace system.directoryservices.activedirectory mostly because the object returned already give some nice properties and methods that I can use to use to perform other actions.

However in previous version of most functions, I was using the System.DirectoryServices.DirectorySearcher (You can take a look in the Archive folder) and the queries were much much faster. The only inconvenient with this one is...that I have to do a lot of work to show each properties and I don't get any methods unfortunately.

Maybe I'm seeing a problem that is not one, and this can be fixed very easily,

Any advices ?

http://stackoverflow.com/questions/23176284/difference-between-principlesearcher-and-directorysearcher

cc: @evetsleep

Set-ADSIUser does not use Credential param

There are a few things with Set-ADSIUser that I addressed or improved.

  • Broken use of -Credential
  • Implemented New-ADSIDirectoryEntry
  • Changed -DomainDN to -DomainName to fall in line with the rest of the module
  • Added DomainDN alias to keep backwards compatibility
  • Added UserPrincipalName to the identity search

Credential Issue

When using Set-ADSIUser -Credential the command was building a Directory Entry, but it did not actually use it. Below you can see the snippet of code where it builds $Cred, but then sets the SearchRoot to $DomainDN instead.

IF ($PSBoundParameters['Credential'])
{
	$Cred = New-Object -TypeName System.DirectoryServices.DirectoryEntry -ArgumentList $DomainDN, $($Credential.UserName), $($Credential.GetNetworkCredential().password)
	$Search.SearchRoot = $DomainDN
}

I have a Pull Request coming that resolves this by implementing the New-ADSIDirectoryEntry. I implemented it the same way as I did in #40 so the Params are not ignored.

DomainName

This command did not follow the same format as the other functions in the module. Since I was going to be implementing New-ADSIDirectoryEntry, I updated the DomainDN param to DomainName so it was the same as the others. To keep backwards compatibility I added DomainDN to the aliases.

UserPrincipalName

I went ahead and added this to the Identity search. This could likely be improved more or maybe utilize some of the other commands in the module. I just stopped with upn because I didn't have the time to look into it further.

Notes

Also, a lot of the default param values are ignored throughout the module. When using the code below in the Begin block, the default values are being ignored since they don't show up in the PSBoundParameters. This means they never get added to the context splat.

IF ($PSBoundParameters['Credential']) { $ContextSplatting.Credential = $Credential }
IF ($PSBoundParameters['DomainName']) { $ContextSplatting.DomainName = $DomainName }

This doesn't seem to impact anything since you have the same defaults set in the commands that use the splat, but just wanted to point it out. You could probably remove all of those default values, but I left them alone since I wasn't sure if you had something planned for them or anything like that.

Get-ADSIGroupMembership

Hello,

This function does not work for AD Groups with lots of members?
I was successful with an AD Group that contains 502 members
Unable to get list with AD Group with 5000+
Are there a limitation?

Thanks

ADSIForest ask for another param

Reproduce :
Get-ADSIForest -ForestName lazywinadmin.com

it will ask to input ContextType Parameter.

Reason :
when specify -ForestName or -Credential , the function call New-ADSIDirectoryContext.
New-ADSIDirectoryContext have ContextType as mandatory parameter.

Add Tags for PowershellGallery

Subject.

Add the following tags to your psd1 file so PSHTML can be displayed on the psgallery if someone search module for a specific Powershell edition (core or desktop)
Tags to add:

'PSEdition_Core','PSEdition_Desktop'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.