I'm working on a powershell script that will do the following:
Will log into our O365 instance
Read the CSV file and update the users attributes (such as department and title)
If the user isn't found, create a new one with those attributes.
If i comment out the New-AzureADUser section it will work fine and update the users that are found, but when i do call New-AzureADUser i get the following error.
New-AzureADUser : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'DisplayName'. Specified method is not supported.
I understand the meaning behind the error in that it wants a string, not an object but i'm a little unsure on next steps.
# Connect to AzureAD
Connect-AzureAD
# Get CSV content
$CSVrecords = Import-Csv bra_o365_import1.csv -Delimiter ","
#CSV contains UserPrincipalName,Department,DisplayName,FirstName,LastName,Title
# Loop trough CSV records
foreach ($CSVrecord in $CSVrecords) {
$upn = $CSVrecord.UserPrincipalName
$user = Get-AzureADUser -Filter "userPrincipalName eq '$upn'"
if ($user) {
try{
$user | Set-AzureADUser -Department $CSVrecord.Department -JobTitle $CSVrecord.Title
} catch {
Write-Warning "$upn user found, but FAILED to update."
}
}
else {
New-AzureADUser -DisplayName $CSVrecords.DisplayName -UserPrincipalName $CSVrecords.UserPrincipalName -AccountEnabled $true -Department $CSVrecord.Department -JobTitle $CSVrecord.Title
Write-Host $CSVrecords.DisplayName
}
}
Related
Hallo I got a question with my update script for my active directory
I am trying to update a user using .csv document
It’s for my understanding very simple but there is an error which I cant find out why it occurs.
My Script:
#Get CSV content
$CSVrecords = Import-Csv "C:\scripts\test.csv" -Delimiter ";"
#Create arrays for skipped and failed users
$SkippedUsers = #()
$FailedUsers = #()
#Loop trough CSV records
foreach ($CSVrecord in $CSVrecords) {
$upn = $CSVrecord.UserPrincipalName
$user = Get-ADUser -Filter "userPrincipalName -eq '$upn'"
if ($user) {
try {
$user | Set-ADUser -Department $CSVrecord.Department -Company $CSVrecord.Company -ErrorAction STOP
}
catch {
$FailedUsers += $upn
Write-Warning "$upn user found, but FAILED to update."
}
}
else {
Write-Warning "$upn not found, skipped"
$SkippedUsers += $upn
}
}
The Date that I am trying to use for the Update:
UserPrincipalName
Department
Company
test.nikola#test.local
Test
123
The Error message that I get: user found, but FAILED to update
Maybe I am blind but i cant find the error ...
As mentioned in the comments, your catch block is hiding all terminating exceptions. Since you never output or inspect the given exception, there's no way to tell what went wrong.
Change it to:
try {
$user | Set-ADUser -Department $CSVrecord.Department -Company $CSVrecord.Company -ErrorAction STOP
}
catch {
$FailedUsers += $upn
Write-Warning "$upn user found, but FAILED to update: $_"
}
Inside the catch block, $_ will refer to the exception that was caught, so at least you now get a chance to see the underlying error message.
I'm working on a script to implement MFA deployment through Powershell. I'm connecting to an office365 and running the Get-MsolUser command to grab a list of users from AD (I believe). I'm putting it into an array which I'm then running through a ForEach loop. I'm not sure if this is even functional yet, but I'm trying to figure out how to exclude certain users from this loop as I don't want to activate MFA for domain admins.
Connect-MsolService
$array = #(Get-MsolUser | Select UserPrincipalName)
ForEach ($users in $array)
{
$st = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
$st.RelyingParty = "*"
$st.State = "Enabled"
$sta = #($st)
Set-MsolUser -UserPrincipalName $users -StrongAuthenticationRequirements $sta
}
So I guess the 3 questions I have are:
How can I exclude users with names matching a certain string such as "Admin, Administrator" in the Array?
Is there anyway to take user input and apply it to the username/password fields for Connect-MsolService?
3)Is this code even functional as it stands or am I totally off the mark?
As commented, there are some enhancements to be made in your code.
Try:
Starting with your question 2)
Connect-MsolService has a -Credential parameter and the easiest way to obtain that is by using the Get-Credential cmdlet:
# ask for credentials to make the connection
$cred = Get-Credential -Message 'Please enter your credentials to connect to Azure Active Directory'
Connect-MsolService -Credential $cred
Next, you want to define a list of users to exclude from being affected.
$excludeTheseUsers = 'admin', 'user1', 'user2' # etc.
# for using the regex `-notmatch` operator later, you need to combine the entries with the regex OR sign ('|'),
# but you need to make sure to escape special characters some names may contain
$excludes = ($excludeTheseUsers | ForEach-Object { [regex]::Escape($_) }) -join '|'
# create the StrongAuthenticationRequirement object just once, to use on all users
$st = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
$st.RelyingParty = "*"
$st.State = "Enabled"
$sta = #($st)
# get an array of UserPrincipalNames
$array = (Get-MsolUser | Where-Object { $_.DisplayName -notmatch $excludes }).UserPrincipalName
foreach ($user in $array) {
Set-MsolUser -UserPrincipalName $user -StrongAuthenticationRequirements $sta
}
I am writing a script that will update Exchange mailbox attributes from a CSV file. When I run my script I get a 'A parameter cannot be found that matches parameter name 'Title'." error. Any ideas. I am tring to change The title property within the organisation tab in Exchange.
I know what the error message means but I can't find anywhere what the syntax is for changing the title attribute.
Script:
# Updates AD user attributes from CSV file
$Credential = Get-Credential
Connect-ExchangeOnline -Credential $Credential
# Load data from file.csv
$ADUsers = Import-csv file_path
# Count variable for number of users update
$count = 0
# Go through each row that has user data in the CSV we just imported
ForEach($User in $ADUsers)
{
# Ppopulate hash table for Get-ADUser splatting:
$GetParams =
#{
Identity = $User.Username
}
# Initialize hash table for Set-ADUser splatting:
$SetParams =
#{
Title = $User.Title
}
# Check to see if the user already exists in AD. If they do, we update.
if ( Get-EXORecipient #GetParams)
{
# Set User attributes
Set-User #SetParams -WhatIf
# Print that the user was updated
Write-Host -ForegroundColor Yellow "$User - User attributes have been updated."
# Update Count
$count += 1
}
}
# Print the number of updated users
Write-Host $count "Users have been updated" -ForegroundColor Green
Error Message:
A parameter cannot be found that matches parameter name 'Title'.
+ CategoryInfo : InvalidArgument: (:) [Set-Mailbox], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Set-Mailbox
+ PSComputerName : outlook.office365.com
Your params for Set-User doesn't contain -Identity so PowerShell doesn't know to whom the title should be set. You need to add it:
$SetParams =
#{
Identity = $User.Username
Title = $User.Title
}
Make sure that Username contains valid identity, so the user can be determined based on it.
I'm pulling some user info from a .csv to create new users,
I've splatted the New User Params at the suggestion of someone here
but I'm getting this error
New-ADUser : The name provided is not a properly formed account name
At C:\Users\Administrator\Documents\GitHub\cyclone-internal-user-sync-1\Bamboo Attributes form a csv.ps1:67 char:17
+ New-ADUser $NewUserParms -ErrorAction Stop
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (CN=System.Colle...=Cyclone,DC=com:String) [New-ADUser], ADException
+ FullyQualifiedErrorId : ActiveDirectoryServer:1315,Microsoft.ActiveDirectory.Management.Commands.NewADUser
the username variable seems to be correct as far as I know, when it outputs during running of the script its what I assume to be correct format of "firstname.lastname"
I have added trims and a section to remove spaces from usernames. to deal with multipart names such as Van der.... etc
#Bamboo Attributes from a .csv
#Enter a path to your import CSV file
$ADUsers = Import-csv 'path'
foreach ($User in $ADUsers) {
$firstName = $user.FirstName.Trim()
$surname = $user.Surname.Trim()
$vaildUsernameFormat = "[^a-zA-Z_.]" # identifies anything that's _not_ a-z or underscore or .
$username = "($firstName'.'$surname)" -replace $vaildUsernameFormat, '' #removes anything that isn't a-z
$DefaultPassword = 'Pa$$w0rd'
$NewUserParms = #{
'samAccountName' = $username;
'Name' = "$firstname $surname";
'DisplayName' = "$firstname $surname";
'UserPrincipalName' = "$username#domain.com";
'GivenName' = $firstname;
'Surname' = $surname;
'EmailAddress' = $User.Email;
'AccountPassword' = (ConvertTo-SecureString $DefaultPassword -AsPlainText -Force);
'Enabled' = $true;
'Path' = "OU=Users,DC=domain,DC=com";
}
write-host "$username this is username value"
#Check if the user account already exists in AD
if (Get-ADUser -F {
sAMAccountName -eq $username
}) {
#If user does exist, output a warning message
Write-Warning "A user account $username has already exist in Active Directory."
}
else {
#If a user does not exist then create a new user account
New-ADUser $NewUserParms -ErrorAction Stop
}
}
I've removed some of the user attributes just to make this a bit smaller.
here is the.csv as well in case I've messed something up there
link to .csv file on git
I think it's something simple. When you use splatting, you need to use the # symbol when feeding your hash table to the cmdlet rather than the regular $:
New-ADUser #NewUserParms -ErrorAction Stop
Some more reading About Splatting.
I am trying to add users in Active Directory. Those users need to have proxyAddresses. My problem is that those proxyAddresses are multiples and stored in an array.
I try :
$proxyAddresses = #("address1#test.com", "address2#test.com", "address3#test.com")
$userInstance = new-object Microsoft.ActiveDirectory.Management.ADUser
$userInstance.ProxyAddresses = $proxyAddresses
New-ADUser test -Instance $userInstance
And I get this error :
Invalid type 'System.Management.Automation.PSObject'. Parameter name: proxyAddresses
I would like to add this proxyAddresses array to the attribute proxyAddresses of my AD user but it don't seem to be possible.
Any idea how this could be done?
Anything wrong with using Set-ADUser?
$username = '...'
$proxyAddresses = 'address1#example.com', 'address2#example.com', 'address3#example.com'
New-ADUser -Name $username
Set-ADUser -Identity $username -Add #{
'proxyAddresses' = $proxyAddresses | % { "smtp:$_" }
}
I just had this same issue and I was pretty sure I was passing in a string array (that's how it was declared).
Problem was just before I sent my string array into AD I was passing it to "Sort-Object -Unique" - which unbeknownst to me was changing either the type or something that made the cmdlet unhappy.
Just FYI...Sort-Object can burn you in these circumstances.
So, in my testing of this. I made Get-ProxyAddresses at https://gist.github.com/PsychoData/dd475c27f7db5ce982cd6160c74ee1d0
function Get-ProxyAddresses
{
Param(
[Parameter(Mandatory=$true)]
[string[]]$username,
[string[]]$domains = 'domain.com'
)
#Strip off any leading # signs people may have provided. We'll add these later
$domains = $domains.Replace('#','')
$ProxyAddresses = New-Object System.Collections.ArrayList
foreach ($uname in $username) {
foreach ($domain in $domains ) {
if ($ProxyAddresses.Count -lt 1) {
$ProxyAddresses.Add( "SMTP:$uname#$domain" ) | Out-Null
} else {
$ProxyAddresses.Add( "smtp:$uname#$domain" ) | Out-Null
}
}
}
return $ProxyAddresses
}
It just returns as a collection. Pretty kludgy, but works for what I need. It also assumes the first username and first domain are the "primary"
I combined that with #ansgar's answer and tried just -OtherAttributes on New-Aduser
$proxyAddresses = Get-ProxyAddress -username 'john.smith', 'james.smith' -domains 'domain.com','domain.net'
New-ADUser -Name $username
-OtherAttributes #{
'proxyAddresses'= $proxyAddresses
}
Works perfectly and added the proxyAddresses for me right at creation, without having to have a separate set action afterwards.
If you are Going to do separate actions, I would recommend to use -Server, like below, so that you don't run into talking to two different DCs by accident (and you also know that the New-ADUser is finished and already there, you don't have to wait for replication)
#I like making it all in one command, above, but this should work fine too.
$ADServer = (Get-ADDomainController).name
New-ADUser -Server $ADServer -name $Username
Set-ADUSer -Server $ADServer -Identity $username -Add #{
'proxyAddresses' = $proxyAddresses | % { "smtp:$_" }
}