Null troubles with PowerShell AD script for creating new users - powershell

Been smooth sailing with creating users for my domain, now I'm trying to set the uidNumber based on what the last 4 digits of the generated objectSid. Might be a simple solution but hoping for some help.
The rest of the code runs fine until we get to the '$last4' variable so I snipped to make it shorter, but if putting the whole script helps, happy to do so.
Import-Module ActiveDirectory
$firstname = Read-Host -Prompt "Please enter the first name"
$lastname = Read-Host -Prompt "Please enter the last name"
$location = Read-Host -Prompt "Please enter user location (LA/NY)"
$path = "OU=Users,OU=$location,OU=GS,DC=random,DC=com"
New-ADUser `
-snip
Add-ADGroupMember `
-Identity "$snip" -Members $username
$user = Get-ADUser -Identity $username
$objectSid = $user.objectSid
$last4DigitsOfObjectSid = $objectSid.Substring($objectSid.Length - 4)
$newUidNumber = "71$last4DigitsOfObjectSid"
Set-ADUser -Identity $username -Replace #{'uidNumber'=$newUidNumber}
Error
You cannot call a method on a null-valued expression.
At C:\Users\Administrator\Desktop\newtry.ps1:31 char:1
$last4DigitsOfObjectSid = $objectSid.Substring($objectSid.Length - 4)
CategoryInfo : InvalidOperation: (:) [], RuntimeException
FullyQualifiedErrorId : InvokeMethodOnNull

objectSid is not an attribute that Get-ADUser returns by default, the attribute you're looking for is just SID. $objectSid in your snippet is actually null, hence the error you're having.
Also, Substring is a String method and SID and objectSid are instances of SecurityIdentifier. This class does not have a Substring method. You would need to refer to the .Value property:
$sid = $user.SID
$last4DigitsOfObjectSid = $sid.Value.Substring($sid.Value.Length - 4)
A much easier way of getting the last 4 digits would be with -replace which will coerce the SecurityIdentifier to a string before replacing:
$sid = $user.SID
$last4DigitsOfObjectSid = $sid -replace '.+(?=.{4}$)'
Or using -split which would also work for SIDs having less than 4 digits:
$last4DigitsOfObjectSid = ($sid -split '-')[-1]

Related

FullyQualifiedErrorId : PositionalParameterNotFound,Add-DistributionGroupMember

I got this little code in PowerShell for O365:
$dispname = Read-Host 'Displayname of room'
$alias = read-Host 'Alias of name (no spaces, no domain)'
$capacity = read-host 'Capacity of room'
$loc = read-host 'Location of room (site)'
$smtp = $alias + "#test.com"
$group = "cr." + $loc + ".all#test.com"
New-Mailbox -Name $alias -DisplayName $dispname -Room -office $loc
Set-Mailbox $alias -ResourceCapacity $capacity
Set-CalendarProcessing $alias -ScheduleOnlyDuringWorkHours $false -AutomateProcessing AutoAccept -AllowRecurringMeetings $True -AllowConflicts $False -ConflictPercentageAllowed 30 -MaximumConflictInstances 10 -BookingWindowInDays 365 -MaximumDurationInMinutes 1440
Set-MailboxCalendarConfiguration -identity $alias -WorkingHoursTimeZone "W. Europe Standard Time" -WorkingHoursStartTime 07:00:00 -WorkingHoursEndTime 18:00:00
Set-MailboxFolderPermission -Identity ${smtp}:\Calendar -User Default -AccessRights Reviewer
echo "Lokation is $loc"
echo "SMTP is $smtp"
echo "Gruppe is $group"
Add-DistributionGroupMember –Identity "$group" –Member "$smtp"
and I'm desperate because only the last line is getting me an error and I have absolutely no clue why.
The error is:
A positional parameter cannot be found that accepts argument
'roomname#test.com'.
CategoryInfo : InvalidArgument: (:) [Add-DistributionGroupMember], ParameterBindingException
FullyQualifiedErrorId : PositionalParameterNotFound,Add-DistributionGroupMember
PSComputerName : outlook.office365.com
So the variable $smtp is correctly set as the email address of the new ressource as well as the variable $group for the group name but somehow it does not work properly for PowerShell.
The thing is, when I do all the steps manually, so paste it in line for line in PowerShellit works. I got the error only when I run it as a script.
The code you pasted contains a character which is not dash
Add-DistributionGroupMember –Identity "$group" –Member "$smtp"
here ^ and here ^
Its output from ASCII Value Tool:
Char Dec Hex Oct
– 150 96 226
While it should be:
Char Dec Hex Oct
- 45 2D 55
Apparently, while pasting it to PowerShell, it's getting converted to - but it doesn't happen when you run the script. Delete the affected line, write it once again and it should work fine.

update/modify ldap user attribute powershell

My powershell script will update the ldap user attribute for non-Microsoft technology(Active Directory) and i faced some issue on it. This is my reference link for how to update non-Microsoft technology(Active Directory)
This is part of my powershell script
if($time -ne $null)
{
$eD = $time.AddDays(7)
write-host "The date after : "$eD
Set-ADUser xxxxx -AccountExpirationDate $eD
$a = New-Object "System.DirectoryServices.Protocols.DirectoryAttributeModification"
write-host $a
$a.Name = "String1"
write-host $a
$a.Operation = [System.DirectoryServices.Protocols.DirectoryAttributeOperation]::Add
write-host $a
#add values of the attribute
$a.Add("set")
write-host $a
$r.Modifications.Add($a)
$re = $ldapserver.SendRequest($r);
if ($re.ResultCode -ne [System.directoryServices.Protocols.ResultCode]::Success)
{
write-host "Failed!"
write-host ("ResultCode: " + $re.ResultCode)
write-host ("Message: " + $re.ErrorMessage)
}
}
Here are my script output
The date after 7 days : 14/1/2020 11:40:03 AM
0
set
You cannot call a method on a null-valued expression.
At D:\deployment\test_ck.ps1:94 char:25
+ $r.Modifications.Add($a)
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
i cant figure out why $a is having a null value
This is what assigned to $r
$Domain='ou=test,ou=tes1,o=test2'
$fDomain ='(objectClass=User)'
$sDomain = New-Object System.DirectoryServices.Protocols.SearchRequest -ArgumentList $Domain,$fDomain,
$r = (new-object "System.DirectoryServices.Protocols.ModifyRequest")
$r = $sDomain
The simple PowerShell script below uses the Get-ADUser cmdlet from the ActiveDirectory PowerShell module to retrieve all the users in one OU and then iterate the users to set a couple of AD properties.
# Get all users in the Finance OU.
$FinanceUsers = Get-ADUser -Filter * -SearchBase "OU=Finance,OU=UserAccounts,DC=FABRIKAM,DC=COM"
# Iterate the users and update the department and title attributes in AD.
The example uses the Instance parameter of Set-ADUser to update each user in the OU. The parameter allows any modifications made to the ADUser object to go to the corresponding Active Directory object while only updating object properties that have changed.

Powershell LDAP Filter with DirectorySearcher

I am using the DirectorySearcher class to find a single user. The criteria should be that the objectCategory is a user, and that his password is not set to never expires.
After some searching, I have come up with this:
$searcher = New-Object System.DirectoryServices.DirectorySearcher
$searcher.Filter = "(&(objectCategory=User)(samAccountName=$env:username)(!(userAccountControl:1.2.840.113556.1.4.803:=65536)))"
where userAccountControl:1.2.840.113556.1.4.803:=65536 should be for users whose password never expires.
Finally I do:
$user = $searcher.FindOne().GetDirectoryEntry()
But it says that I cannot call a method on a null-valued expression. I think I am using the parentheses correctly. So then could it be that I can't use the ! operator for this?
Also note that I could use the get-aduser command, like so:
get-aduser -filter * -properties samAccountName, PasswordNeverExpires | where { $_.passwordNeverExpires -eq "true" } | where {$_.enabled -eq "true"} | where {$_.samAccountName -eq $env:username}
but in this instance it would be preferable to use the DirectorySearcher instead like shown above.
In fact your code is working, but when the $searcher.FindOne() return nothing, that is to say, when the filter return nothing, the GetDirectoryEntry() method give :
> You cannot call a method on a null-valued expression. At line:1 char:1
> + $searcher.FindOne().GetDirectoryEntry()
> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> + CategoryInfo : InvalidOperation: (:) [], RuntimeException
> + FullyQualifiedErrorId : InvokeMethodOnNull
Try :
$user = $searcher.FindOne()
if($user -ne $null) {$user.GetDirectoryEntry()} else {write-host "Niet"}

Error: "New-ADUser : The object name has bad syntax"

I am creating a PowerShell script at work to copy user accounts. The script works perfectly on my test Server 2016 VM. It also works in our work environment on a coworkers Windows 10 PC, however I cannot run it on my local machine. It returns the following error:
New-ADUser : The object name has bad syntax
At line:155 char:1
+ New-ADUser -Name $New_DisplayName #params
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (CN=cnelson test...ctions,DC=local:String) [New-ADUser], ADException
+ FullyQualifiedErrorId : ActiveDirectoryServer:8335,Microsoft.ActiveDirectory.Management.Commands.NewADUser
Add-ADGroupMember : Cannot find an object with identity: 'cnelsontest1' under:
'DC=,DC=local'.
At line:159 char:29
+ Add-ADGroupMember -Members $Username.Text
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (cnelsontest1:ADPrincipal) [Add-ADGroupMember], ADIdentityNotFoundException
+ FullyQualifiedErrorId : SetADGroupMember.ValidateMembersParameter,Microsoft.ActiveDirectory.Management.Commands.AddADGroupMember
$params = #{'SamAccountName' = $Username.Text;
'Instance' = $AD_Account_To_Copy;
'DisplayName' = $New_DisplayName;
'GivenName' = $FirstName.Text;
'Path' = $New_Path;
'SurName' = $LastName.Text;
'ChangePasswordAtLogon' = $true;
'Enabled' = $true;
'UserPrincipalName' = $Username.Text;
'AccountPassword' = $New_Pass;
'EmailAddress' = $Username.Text + '#azcorrections.gov';
'HomePage' = $HomePage.HomePage;
'Description' = $NewDescription.Description;
'Office' = $NewOffice.Office;
'StreetAddress' = $NewStreet.StreetAddress;
'City' = $NewCity.City;
'State' = $NewState.State;
'PostalCode' = $NewPostalCode.PostalCode;
'Title' = $NewTitle.Title;
'Department' = $NewDepartment.Department;
'Company' = $NewCompany.Company;
'ScriptPath' = $NewScript.ScriptPath;
'OfficePhone' = $PhoneNumber.text;
}
New-ADUser -Name $New_DisplayName #params
Full Script link
I'm running PSVersion 5.1.150
Any ideas as to what i'm missing and why i'm coming across this error? I have no idea what it is referring to, nor why it works on one coworkers computer but not my own.
Edit: Value of $params at the time of the error:
Name Value
---- -----
AccountPassword System.Security.SecureString
Description Chris Nelson Test Account
UserPrincipalName cnelsontest1
HomePage http://...
DisplayName cnelson test1
SamAccountName cnelsontest1
ScriptPath
EmailAddress cnelsontest1#example.com
Office test
GivenName cnelson
Title SYSTEMS/LAN ADMR
Company
OfficePhone 555-1234
StreetAddress Sesame Street
PostalCode 54321
SurName test1
State candid
Department IT
ChangePasswordAtLogon True
Path cnelson,OU=IT_TECHSRVS,OU=Information Technology,OU=ADMIN,OU=CENT_OFF,DC=example,DC=com
City
Enabled True
Instance CN=test\, cnelson,OU=IT_TECHSRVS,OU=Information Technology,OU=ADMIN,OU=CENT_OFF,DC=example,DC=com
I'm calculating $New_Path like this:
$New_Path = (Get-ADUser ($UsernameCopy.Text)).DistinguishedName -replace '^.*?,', ''
The way you remove the common name portion from the value of $AD_Account_To_Copy is flawed. -replace '^.*?,', '' will remove everything up to the first comma in the string. If the common name itself contains a comma (like in CN=test\, cnelson,OU=...) the replacement won't remove cnelson,. Amend your regular expression with a positive lookahead assertion, so that everything before the first OU= is removed:
$New_Path = $AD_Account_To_Copy -replace '^.*?,\s*(?=ou=)', ''

New-ADGroup - Using -join and Variable in a PS cmdlet?

I've been delving into PS scripting over the last few months and I was attempting to script out AD group creations. Right now, I'm asking the following:
$GroupNameRO = Read-Host -Prompt 'What Read Only AD group name do you want to use'
$GroupNameRW = Read-Host -Prompt 'What Read Write AD group name do you want to use'
$RequestNum = Read-Host -Prompt 'Input the request number for this share'
Then putting it all together here:
New-ADGroup -name $GRPnameRW -path 'OU=Security,OU=Groups,DC=test,DC=local' -groupscope 'global' -Description -join('Request #',$RequestNum)
and finally receiving this error:
New-ADGroup : A positional parameter cannot be found that accepts argument 'System.Object[]'.
At line:1 char:1
+ New-ADGroup -name $GRPnameRW -path 'OU=Security,OU=Groups,DC=test,DC=local' -g ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-ADGroup], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.ActiveDirectory.Management.Commands.NewADGroup
Has anyone used the -join within a parameter / am I formatting everything correctly?
... -Description (('Request #',$RequestNum) -join 'something')
You need to do it like this. Think of it this way:
-Description (expression)
because Description has to be a result of an expression we need to enclose the expression in (), everything inside () gets executed first.
And for -join to work we need to feed values into it, so:
(values) -join 'what_are_we_joining_with'
ps. you don't really need () around values you are passing to join in some cases: 'a','b' -join "" works. But I thinks its nicer this way and more intuitive with ().
Your value for the -Description parameter is incorrect. This should get you the result you're looking for:
New-ADGroup -name $GRPnameRW -path 'OU=Security,OU=Groups,DC=test,DC=local' -groupscope 'global' -Description "Request #$RequestNum"