Set default server in powershell for AD related commands - powershell

Recently my powershell scripts require to explicitly say which domain I want to connect to. Is it necessary to write this for each command? Or can I set it somehow once in the beginning of the script.
Instead of
Get-ADUser -Server server otherparameters
could I write in the beginning something like
Set-default server to connect to
?

Is it necessary to write this for each command?
No!
You can specify a default parameter value for a parameter belonging to one or more cmdlets by assigning it to the $PSDefaultParameterValues automatic variable:
$PSDefaultParameterValues['*-AD*:Server'] = 'mydc.mydomain.tld'
Any cmdlet you subsequently invoke that matches the *-AD* pattern by name and has a -Server parameter will now implicitly have 'mydc.mydomain.tld' bound to the -Server parameter unless an argument is explicitly passed.
In other words: next time you invoke Get-ADUser rsterba, PowerShell now calls Get-ADUser rsterba -Server 'mydc.mydomain.tld' instead.
For more information about $PSDefaultParameterValues and how it works, see the about_Parameters_Default_Values help topic

Related

Get-Help shows different outputs on different systems

When I use the following cmdlet:
Get-Help Get-ADUser -Parameter identity
On Windows 7 with RSAT installed connecting to Windows Server 2012 R2, I get the following output:
-Identity <ADUser>
Specifies an Active Directory user object by providing one of the following property values. The identifier in
parentheses is the LDAP display name for the attribute.
Distinguished Name
Example: CN=SaraDavis,CN=Europe,CN=Users,DC=corp,DC=contoso,DC=com
GUID (objectGUID)
Example: 599c3d2e-f72d-4d20-8a88-030d99495f20
Security Identifier (objectSid)
Example: S-1-5-21-3165297888-301567370-576410423-1103
SAM account name (sAMAccountName)
Example: saradavis
The cmdlet searches the default naming context or partition to find the object. If two or more objects are found
the cmdlet returns a non-terminating error.
This parameter can also get this object through the pipeline or you can set this parameter to an object instance
This example shows how to set the parameter to a distinguished name.
-Identity "CN=SaraDavis,CN=Europe,CN=Users,DC=corp,DC=contoso,DC=com"
This example shows how to set this parameter to a user object instance named "userInstance".
-Identity $userInstance
Required? true
Position? 1
Default value
Accept pipeline input? true (ByValue)
Accept wildcard characters? false
However when I use it on a Windows Server 2012 R2 or 2016 with WMF 5.1 installed I only get the following:
-Identity <ADUser>
Required? true
Position? 1
Default value
Accept pipeline input? true (ByValue)
Accept wildcard characters? false
Any idea what I'm doing wrong?
Get-ADUser command comes from a 'system module' that can be different from an OS to an other even with the same version of WMF and even if the version number shown by 'Get-Command Get-ADUser' is the same (1.0.0.0) ... so help content may be different too.
By the way, I get this result on my Windows 2012 R2 with WMF 5.1
-Identity <ADUser>
Specifies an Active Directory user object by providing one of the following property values. The identifier in
parentheses is the LDAP display name for the attribute. The acceptable values for this parameter are:
-- A Distinguished Name
-- A GUID (objectGUID)
-- A Security Identifier (objectSid)
-- A SAM Account Name (sAMAccountName)
The cmdlet searches the default naming context or partition to find the object. If two or more objects are found,
the cmdlet returns a non-terminating error.
This parameter can also get this object through the pipeline or you can set this parameter to an object instance.
Required? true
Position? 1
Default value
Accept pipeline input? True (ByValue)
Accept wildcard characters? false
You may try Update-Help to download latest PowerShell help files (if your server is connected to Internet...).

Get-ADForest - Could not find a forest identified by: "xxxx"

Here's the command I run:
$Credentials = Get-Credential # Feed in credentials for some.domain.com
Get-ADForest -Server some.domain.com -Credential $Credentials
And it reports:
Get-ADForest : Could not find a forest identified by: 'some.domain.com'
I've tried all kinds of different things for the -Server parameter, including using the hostname.domain.name.com and nothing works. Is it possible it is being blocked?
However, if I run a:
Get-ADUser username -Server 'some.domain.com' -Credential $Credentials
It returns the value...
First of all, you need to go through the documentation for Get-ADForest to understand what might be happening in your case:
The Get-ADForest cmdlet gets the Active Directory forest specified by
the parameters. You can specify the forest by setting the Identity or
Current parameters..........
To retrieve the forest of the local computer or current logged on user
(CLU), set the Current parameter to LocalComputer or LoggedOnUser. When
you set the Current parameter, you do not need to set the Identity
parameter.......
When the Current parameter is set to LocalComputer or LoggedOnUser,
the cmdlet uses the Server and Credential parameter values to
determine the domain and the credentials to use to identify the domain
of the forest according to the following rules......
-- If the Server and Credential parameters are specified:
The domain is set to the domain of the specified server and the cmdlet
checks to make sure that the server is in the domain of the
LocalComputer or LoggedOnUser. Then the credentials specified by the
Credential parameter are used to get the domain. An error is
returned when the server is not in the domain of the LocalComputer or
LoggedOnUser.
I believe the error which you're receiving is because the last line is not being satisfied. Please verify the same in your case because it seems the server which you're specifying is either not in the domain of the LocalComputer or the LoggedOnUser.
First of all, the two examples you mention, are two different CMDlets. Let's not confuse the two of them.
About Get-ADForest:
Judging upon the information from this fact sheet about Get-ADForest
Would it help you to use -Identity "some.domain.com" instead? From what i can gather, either you use the -Identity switch(which is mandatory), or you pipe an object to the CMDlet.
The Identity switch takes these values:
A fully qualified domain
A GUID (objectGUID)
A DNS host name
A NetBIOS name
Test:
Get-ADForest -Identity 'some.domain.com' -Credential $Credentials

How to run powershell script against domain?

I am trying to run the following powershell command through my application using C#
Get-ADUserResultantPasswordPolicy user1
It returns the values for user1 on domain1 which is my current domain.
when I try to read the values for a user2 on domain2:
Get-ADUserResultantPasswordPolicy domain2\user2
its throwing exception
"Cannot find an object with identity:'user2' under:'DC=domain2,DC=com'.
Is there away to point powershell to the other domains and read the data on that domain?
Use the -partition parameter:
Specifies the distinguished name of an Active Directory partition. The distinguished name must be one of the naming contexts on the current directory server. The cmdlet searches this partition to find the object defined by the Identity parameter.
The following two examples show how to specify a value for this parameter.
-Partition "CN=Configuration,DC=EUROPE,DC=TEST,DC=CONTOSO,DC=COM"
-Partition "CN=Schema,CN=Configuration,DC=EUROPE,DC=TEST,DC=CONTOSO,DC=COM"
Read more here: https://technet.microsoft.com/en-us/library/ee617255.aspx?f=255&MSPPError=-2147217396
You can use the -Server parameter with the fully qualified domain name of the domain controller on domain you want to access.
Get-ADUserResultantPasswordPolicy -Identity "USER1" -Server "DC1.YourDomain.com"

How can I tell if I'm in a remote PowerShell session?

I would like to execute code that is specific to remote PSSessions. That is, the code doesn't apply locally, but applies to all remote sessions.
Is there any environment variable, function or cmdlet that would effectively return true if I'm in an active PSSession and false if I'm running locally?
Check if the $PSSenderInfo variable exists. From about_Automatic_Variables:
$PSSenderInfo
Contains information about the user who started the PSSession,
including the user identity and the time zone of the originating
computer. This variable is available only in PSSessions.
The $PSSenderInfo variable includes a user-configurable property,
ApplicationArguments, which, by default, contains only the
$PSVersionTable from the originating session. To add data to the
ApplicationArguments property, use the ApplicationArguments parameter
of the New-PSSessionOption cmdlet.
You could also test using this:
If ( (Test-Path variable:PSSenderInfo)
        -and ($Null -ne $PSSenderInfo)
        -and ($PSSenderInfo.GetType().Name -eq 'PSSenderInfo') ) {
    Write-Host -Object "This script cannot be run within an active PSSession"
    Exit
}
This was not my initial finding, but it helped with "variable PSSenderInfo not set" issue, if it doesn't exist.

How do I pass common powershell command line parameters between cmdlets on the pipeline?

Say I've got two cmdlets, 'new-foo' and 'do-bar'. Both cmdlets need to authenticate to a service in order to perform their action, and 'do-bar' takes a foo. Today, I can do:
new-foo -host localhost -username user -password password -whateverOtherArgs
And I can do:
do-bar -host localhost -username user -password password -foo myFoo
And I can even chain them passing foo on the pipeline, e.g.:
new-foo <blah blah> | do-bar -host localhost -username user -password password
But I can't figure out how to pass the common parameters, such as the service location and the credentials between elements of the pipeline. If I've got a bunch of my cmdlets chained together I'd like to only pass the credentials the first time, and then re-use those for the rest of the pipeline.
What am I missing, seems like this should be obvious ...
You could have New-Foo spit out an object that contains both the original object that do-bar is interested in as well as the service location and the credentials as properties. Accept this object as a parameter and then pluck out the data you need if the user doesn't supply the ServiceLocation or Credential parameters.
does Get-Credential cover you need.
Are you developing this cmdlets, or are you just using them in your scripts?
If you are writing these cmdlets in any OOP language, I think a way to do it is that you have a base cmdlet class, and every other cmdlets should extend that base cmdlet class. In this case, the base cmdlet class should initialize an object that stores your credential, and have a cmdlet to ask for credentials, which initialize the object. Every other cmdlets that extends the base class can therefore look for credential in this object.