Powershell - Generating username for Active Directory - powershell

I'm trying to create a script that creates a unique user I Active Directory.
Before the script can create a user it needs to make sure the username is available by asking two different domains if the generated username exists. The problem is I don't how generate a new username or rerun part of the script if necessary. Lets say that if the generated username exists in one of the domains I wan't to generate a new username and try again with the new one. This is what I have so far.
Import-Module ActiveDirectory
$firstname = "Test"
$lastname = "Tester"
$SecondaryDomain = "server1.domain1.net"
$PrimaryDomain = "server2.domain2.net"
$ErrorActionPreference = "SilentlyContinue"
$Generate = [Char[]]"$firstname$lastname"
$Generatedusername = ($Generate | Get-random -Count 3) -join ""
Write-host $Generatedusername
if (Get-ADUser -Filter {SamAccountName -eq $Generatedusername} -Server $PrimaryDomain)
{
#If the variable equals 1 the user exists
$PrimaryDomainOK = "1"
}
else
{
$PrimaryDomainOK = "0"
}
if (Get-ADUser -Filter {SamAccountName -eq $Generatedusername} -Server $SecondaryDomain)
{
#If the variable equals 1 the user exists
$SecondaryDomainOK = "1"
}
else
{
$SecondaryDomainOK = "0"
}
Write-host "Primary Domain $PrimaryDomainOK"
Write-host "Secondary Domain $SecondaryDomainOK"
If ($PrimaryDomainOK -and $SecondaryDomainOK -eq 0)
{
Write-host "Creating Account"
}
Else
{
Write-host "Can't create account"
}

Add a while statement embracing your generation/verification which checks for the status of $PrimaryDomainOK and $SecondaryDomainOK.
...
$Generate = [Char[]]"$firstname$lastname"
while(($PrimaryDomainOK -ne 0) -and ($SecondaryDomainOK -ne 0)) {
$Generatedusername = ($Generate | Get-random -Count 3) -join ""
Write-host $Generatedusername
...
...
...
If ($PrimaryDomainOK -and $SecondaryDomainOK -eq 0)
{
Write-host "Creating Account"
}
Else
{
Write-host "Can't create account"
}
}
Remember the closing brace.

Related

How do I use a switch statement with while loop

I am trying to add a user to the Remote Desktop group using Powershell.
It seems it's not breaking the loop and doesn't execute further statements.
Can you please help me where the issue is:
$remote = ""
While($remote -ne "Y" ){
$remote = read-host "Do you need to add anyone to the Remote Desktop group (y/n)?"
Switch ($remote)
{
Y {
$remoteuser = ""
while ( ($remoteuser -eq "") -or ($UserExists -eq $false) )
{
$remoteuser = Read-Host "Enter the username that needs to be in the group"
Write-Host "User inputted $remoteuser"
sleep -Seconds 2
try {
Get-ADUser -Identity $remoteuser -Server <server-FQDN>
$UserExists = $true
Write-Host "$remoteuser found!"
sleep 5
}
catch [Microsoft.ActiveDirectory.Management.ADIdentityResolutionException] {
Write-Host "User does not exist."
$UserExists = $false
}
catch {
Write-Host "Username is blank"
$UserExists = $false
}
}
}
N {Write-Host "No user accounts will be added to the Remote Desktop Users group. Restart your PC."}
default {Write-Host "Only Y/N are Valid responses"}
}
}
<further statements>

Powershell - Azure licence based on ad group

I have been developing AzureAD licence script based on AD Group. So, Find users with a direct assigned, find them in AD, evaluate what group they should be a member of, add them to licensing group. I have hashtable with multiple values $SKUToGroupRev. I can not match hashtable with multiple values with if($ADGroup = $SKUToGroupRev[$SKU.SkuId]) .
From what I want to do :
if there are 18181a46-0d4e-45cd-891e-60aabd171b4e and 0c266dff-15dd-4b49-8397-2bb16070ed52 inside SKUs variable for below command then I will add AD group related to the inside hashtable such as O365_E1_Users
OR
if there are 6fd2c87f-b296-42f0-b197-1e91e994b900 and 0c266dff-15dd-4b49-8397-2bb16070ed52 inside SKUs variable for below command then I will add AD group related to the inside hashtable such as O365_E3_Users
e.g:
# Get licensed SKUs for the user
$aaduser = get-azureaduser -objectID $user.UserPrincipalName
$SKUs = $aaduser | Select UserPrincipalName,ImmutableID -ExpandProperty AssignedLicenses
e.g output:
UserPrincipalName ImmutableId DisabledPlans SKUId
----------------- ----------- ------------- -------------
User01#contoso.com x+MVG6EKEUWHi3r6zjgzCA== {041fe683-03e4-45b6-b1af-c0cdc516da4f... 6fd2c87f-b296-42f0-b197-1e91e994b900
User01#contoso.com x+MVG6EKEUWHi3r6zjgzCA== {} 0c266dff-15dd-4b49-8397-2bb16070ed52
Here is my script :
$CSVfile = "C:\temp\LicenseToGroupUsers.csv"
# Import the CSV file
try {
$users = import-csv $CSVfile
}
catch {
$errorZero = $Error[0]
write-host "Error: " $errorZero -ForegroundColor Red #Writes the latest error
Break
}
write-warning "About to add the following users to license groups for complete SKU:"
foreach ($user in $users){
write-host $user.UserPrincipalName
}
Read-Host -Prompt "Press Enter to continue or CTRL+C to quit"
$e3 = -split "0c266dff-15dd-4b49-8397-2bb16070ed52 6fd2c87f-b296-42f0-b197-1e91e994b900"
$e1 = -split "18181a46-0d4e-45cd-891e-60aabd171b4e 0c266dff-15dd-4b49-8397-2bb16070ed52"
$TEAMS_EXPLORATORY = -split "710779e8-3d4a-4c88-adb9-386c958d1fdf 0c266dff-15dd-4b49-8397-2bb16070ed52"
#$FLOW_FREE_E3 = -split "f30db892-07e9-47e9-837c-80727f46fd3d 6fd2c87f-b296-42f0-b197-1e91e994b900 0c266dff-15dd-4b49-8397-2bb16070ed52"
foreach ($user in $users){
$groupsToAdd = #()
$groupsToRemove = #()
write-host "Processing" $user.UserPrincipalName
# Get licensed SKUs for the user
$aaduser = get-azureaduser -objectID $user.UserPrincipalName
#$SKUs = $aaduser | Select UserPrincipalName,ImmutableID -ExpandProperty AssignedLicenses
#Get the AD ObjectGuid for the group add (cannot use UPN)
$ImmutableID = "" #Null these out otherwise gets reused from previous
#Have to match using the guid
$ImmutableID = $aaduser.ImmutableID
if ($ImmutableID) {$objectGUID = ([GUID][System.Convert]::FromBase64String($ImmutableID)).Guid}
else {
write-warning "Error getting ImmutableID for $UPN, user is likely cloud only, skipping"
Break
}
# test 1
$licenses = $aaduser.AssignedLicenses.SkuId
$is_e1 = !($e1 | ForEach-Object { $licenses.Contains($_) }).Contains($false)
if($is_e1 -eq "True"){
try {
write-host "Adding" $user.UserPrincipalName"to E1Group" -ForegroundColor Green
Write-Host "Test 1: $is_e1"
}
catch {
$errorZero = $Error[0]
write-host "Error: " $errorZero -ForegroundColor Red #Writes the latest error
}
}
$is_e3 = !($e3 | ForEach-Object { $licenses.Contains($_) }).Contains($false)
if($is_e3 -eq "True"){
try {
write-host "Adding" $user.UserPrincipalName"to E3Group" -ForegroundColor Green
Write-Host "Test 3: $is_e3"
}
catch {
$errorZero = $Error[0]
write-host "Error: " $errorZero -ForegroundColor Red #Writes the latest error
}
}
$is_TEAMS_EXPLORATORY = !($TEAMS_EXPLORATORY | ForEach-Object { $licenses.Contains($_) }).Contains($false)
if($is_TEAMS_EXPLORATORY -eq "True"){
try {
write-host "Adding" $user.UserPrincipalName"to (TEAMS_EXPLORATORY)E1Group" -ForegroundColor Green
Write-Host "Test 1: $is_TEAMS_EXPLORATORY"
}
catch {
$errorZero = $Error[0]
write-host "Error: " $errorZero -ForegroundColor Red #Writes the latest error
}
}
<# $is_FLOW_FREE_E3 = !($FLOW_FREE_E3 | ForEach-Object { $licenses.Contains($_) }).Contains($false)
if($is_FLOW_FREE_E3 -eq "True"){
try {
write-host "Adding" $user.UserPrincipalName"to (FLOWFREE)E3Group" -ForegroundColor Green
Write-Host "Test 1: $is_FLOW_FREE_E3"
}
catch {
$errorZero = $Error[0]
write-host "Error: " $errorZero -ForegroundColor Red #Writes the latest error
}
}#>
}
To test agains a combination of SkuID's, using a lookup hashtable as in your first approach is not the easiest way I think. Your current approach looks much better to me, only I would not put the ID's in array variables, but test them literally against the ID's as they are found in the users AssignedLicenses.
Something like this:
$CSVfile = "C:\temp\LicenseToGroupUsers.csv"
# Import the CSV file
$users = Import-Csv -Path $CSVfile
Write-Warning "About to add the following users to license groups for complete SKU:"
$users.UserPrincipalName -join [environment]::NewLine
Write-Host
$answer = Read-Host -Prompt "Press Enter to continue or Q to quit"
if ($answer[0] -eq 'Q') { Clear-Host; exit }
foreach ($user in $users) {
Write-Host "Processing" $user.UserPrincipalName
$ImmutableID = $null # Null these out
$ADGroup = $null
# Get licensed SKUs for the user
$aaduser = Get-AzureADUser -objectID $user.UserPrincipalName
# Get the AD ObjectGuid for the group add (cannot use UPN)
# Have to match using the guid
$ImmutableID = $aaduser.ImmutableID
if (![string]::IsNullOrWhiteSpace($ImmutableID)) {
$objectGUID = ([GUID][System.Convert]::FromBase64String($ImmutableID)).Guid}
else {
Write-Warning "Error getting ImmutableID for $($user.UserPrincipalName), user is likely cloud only, skipping"
continue # skip this one and proceed with the next user
}
$licenses = #($aaduser.AssignedLicenses.SkuId) # force it to be an array
##########################################################################################
# Apparently, SkuId '0c266dff-15dd-4b49-8397-2bb16070ed52' is needed for all combinations,
# so we could already rule out users that do not have that ID in their $licenses..
# if that is indeed the case, you can simplify al other tests by not having to check
# for this ID every time..
# for now, this is an assumption, so commented out.
# if (!($licenses -contains '0c266dff-15dd-4b49-8397-2bb16070ed52')) {
# Write-Warning "Could not determine a group for user $($user.UserPrincipalName)"
# continue # skip this one and proceed with the next user
# }
##########################################################################################
# test E1: 'Microsoft 365 Audio Conferencing' and 'OFFICE 365 E1'
if ($licenses -contains '0c266dff-15dd-4b49-8397-2bb16070ed52' -and
$licenses -contains '18181a46-0d4e-45cd-891e-60aabd171b4e') {
# Add this user to group 'O365_E1_Users'
$ADGroup = 'O365_E1_Users'
}
# test E3: 'Microsoft 365 Audio Conferencing' and 'OFFICE 365 E3'
elseif ($licenses -contains '0c266dff-15dd-4b49-8397-2bb16070ed52' -and
$licenses -contains '6fd2c87f-b296-42f0-b197-1e91e994b900') {
if ($licenses -contains 'f30db892-07e9-47e9-837c-80727f46fd3d') { # also 'MICROSOFT FLOW FREE' ?
# Add this user to group 'FLOW_FREE_E3'
$ADGroup = 'FLOW_FREE_E3'
}
else {
# Add this user to group 'O365_E3_Users'
$ADGroup = 'O365_E3_Users'
}
}
# test 'Microsoft 365 Audio Conferencing' and 'MICROSOFT TEAMS EXPLORATORY'
elseif ($licenses -contains '0c266dff-15dd-4b49-8397-2bb16070ed52' -and
$licenses -contains '710779e8-3d4a-4c88-adb9-386c958d1fdf') {
# Add this user to group 'TEAMS_EXPLORATORY'
$ADGroup = 'TEAMS_EXPLORATORY'
}
# finished the conditions, now see if we can add the user to one of the groups
if (![string]::IsNullOrWhiteSpace($ADGroup)) {
try {
Write-Host "Adding $($user.UserPrincipalName) to $ADGroup" -ForegroundColor Green
# Add-ADGroupMember -Identity $ADGroup -Members $objectGUID
}
catch {
Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
}
}
else {
Write-Warning "Could not determine a group for user $($user.UserPrincipalName)"
}
}

Unable to close down called PowerShell window on completion

I have a VBScript that runs a PowerShell script. The PowerShell script completes, but it just shows a black window that does not close and go back to the VBScript. If I close the black window the script continues. The PowerShell script itself does run and exit if ran on its own. Here is the my VBScript that executes the PowerShell script:
Set objFSO = CreateObject("Scripting.FileSystemObject")
strUSer = InputBox("Enter the username you wish to test the object for. if there is more than one please put a space between each.")
UserArray = Split(strUser)
For Each x In UserArray
strMessage = strMessage & x & vbCrLf
Next
Set objTextFile = objFSO.CreateTextFile("C:\scripts\UserTest.txt", True)
objTextFile.Write (strMessage)
objTextFile.Close
Set objTextFile = Nothing
WScript.Sleep 2000
Set objShell = CreateObject("WScript.Shell")
strChatterCommand = "powershell.exe -ExecutionPolicy Bypass -NoLogo -File C:\scripts\User_Check.ps1"
Set RunChatter = objShell.Exec(strChatterCommand)
strText = ""
Do While Not RunChatter.StdOut.AtEndOfStream
strText = strText & RunChatter.StdOut.ReadLine() & vbCrLf
Loop
WScript.Echo strText
Set fso = Nothing
Set RunChatter = Nothing
WScript.Quit
Powershell script:
#Region Set Variables & Env
$SalesforceCsv = "\\some\path$\Platform_LiveExtract.csv"
$aOutput = #()
#EndRegion Set Variables & Env
#Region Functions
Function Install-ADcmdlets{
#Ensure Group Policy module is installed
if ((Get-Module | ? {$_.Name -eq "activedirectory"}) -eq $null){
$ErrorActionPreference = "stop"
Try{
import-module activedirectory
}Catch{
Write-Host "Please install the Active Directory powershell cmdlets. Exiting Script..."
exit
}
}
}
Function get-ChatterCsvDetails ($fCsv, $FedID){
$Return = ($fCsv | ? {$_.FEDERATIONIDENTIFIER -eq $FedID})
if (!($Return)){
Write-Host "No User Account found in Chatter..."
}else{
Write-Host "$FedID found in Chatter"
Write-Host (" - Chatter Account created: " + $Return.CREATEDDATE.subString(0,10))
Write-Host (" - Chatter Account last logon: " + $Return.LASTLOGINDATE.subString(0,10))
}
Return $Return
}
Function Pause-Script{
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
exit
}
Function Get-DomainFromDN ([string]$fDN){
[string]$fReturn = ""
[array]$fSplit = $fDN -split ",DC="
for([int]$i=1; $i -le ($fSplit.count -1); $i++){
$fReturn += ("." + $fSplit[$i])
}
return $fReturn.substring(1,($fReturn.length -1))
}
Function Check-ADObjectChatterReadiness ($fUser, $fCsv){
$fErrorsFound = $False
$fUserDomain = (Get-DomainFromDN $fUser.DistinguishedName)
Write-Host ("Checking object " + $fUserDomain + "\" + ($fUser.Samaccountname))
#Check Samid cases match FederationID
if ($fCsv){
If ($fUser.samaccountname -cne $fCsv.FEDERATIONIDENTIFIER){
Write-host ("ACTION: Users SamId is in the wrong case. Please change it to " + $fCsv.FEDERATIONIDENTIFIER)
$fErrorsFound = $True
}
}
#Check first Name not blank
if (!($fUser.GivenName)){
Write-host "ACTION: User's GivenName is blank"
$fErrorsFound = $True
}
#Check last name not blank
if (!($fUser.SN)){
Write-host "ACTION: User's Surname is blank"
$fErrorsFound = $True
}
#Check DisplayName is not blank
if (!($fUser.displayName)){
Write-host "ACTION: User's Display Name is blank"
$fErrorsFound = $True
}
#Check UPN is not blank
If (!($fUser.userprincipalName)){
Write-host "ACTION: User's UPN is blank"
$fErrorsFound = $True
}else{
#Check UPN for illegal characters
if ($fUser.userprincipalName.ToString().contains(" ")){
Write-host "ACTION: User's UPN contains a space"
$fErrorsFound = $True
}
}
#Check Email for space
if ($fUser.Mail){
if ($fUser.Mail.contains(" ")){
Write-host "ACTION: User's Email contains a space"
$fErrorsFound = $True
}
}
#Check User is in the correct OU
if ($fUserDomain -eq "bskyb.com"){
if ($fUser.DistinguishedName -notlike "*,OU=User Accounts,DC=bskyb,DC=com"){
write-host "ACTION: Bskyb User account is not in a supported OU"
$fErrorsFound = $True
}
}else{
if ($fUser.DistinguishedName -notlike "*,OU=User Accounts,DC=Ext,DC=bskyb,DC=com"){
write-host "ACTION: Ext User account is not in a supported OU"
$fErrorsFound = $True
}
}
#If chatter account doesn't exist, check user is a member of federation group
if (!($fCsv)){
if ($fUser.extensionattribute2)
{
write-host "ACTION: Clear the users ExtensionAttribute2 value.`nAttempting to clear attribute now..."
try{
Set-ADUser $fUser -clear Extensionattribute2 -Server $fUserDomain
Write-Host "ACTION: SUCCESS - Attribute value cleared... please get the user to retest."
}
catch{
Write-Host "ACTION: FAILED... please manually clear the attribute value."
}
$fErrorsFound = $True
}
}
else
{
if (!($fUser.extensionattribute2))
{
write-host "ACTION: Set the users ExtensionAttribute2 value.`nAttempting to set attribute now..."
try{
set-aduser $fUser -Add #{extensionAttribute2="ChatterUser"} -Server $fUserDomain
Write-Host "ACTION: SUCCESS - Attribute value set... please get the user to retest."
}
catch{
Write-Host "ACTION FAILED... please manually set the attribute value."
}
$fErrorsFound = $True
}
}
#Check account is enabled
If ($fUser.Enabled -eq $false){
write-host "ACTION: User account is disabled in Active Directory"
$fErrorsFound = $True
}
#Check account is not a member of Deactivated group
$fUser.MemberOf | % {
if ($_ -like "*APP-CHATTER-DEACTIVATED*"){
write-host "ACTION: User has been de-activated from Chatter. Please check with Chatter team."
$fErrorsFound = $True
}
}
#Check for errors
if ($fErrorsFound -eq $False){
Write-host "No issues found with Active Directory object"
}
}
Function Check-ChatterUser ($fCsv, $fSamid){
Write-Host `n"--------------------------------------------------"
Write-Host "------------ Checking account $fSamid ------------"
$fChatterIssues = ""
$fLdapFilter = ('(samaccountname=' + $fSamid + ')')
$fAdCmdletUser = (get-aduser -LDAPFilter $fLdapFilter -server bskyb.com:3268 -Properties givenName,sn,mail,displayName,memberof,ExtensionAttribute2)
if ($fAdCmdletUser){
# User/s found
$oChatterUser = get-ChatterCsvDetails $fCsv $_
if (($fAdCmdletUser.count) -and ($fAdCmdletUser.count -ge 2)){
# samid In both domains
$fAdCmdletUser | % {
Check-ADObjectChatterReadiness $_ $oChatterUser
}
}else{
# 1 User returned
Check-ADObjectChatterReadiness $fAdCmdletUser $oChatterUser
}
}else{
#No User found
Write-Host "No user with samaccoutname found in GC"
}
Write-Host "`n------ Complete ------"
}
#EndRegion Functions
#Region Main body
Install-ADcmdlets
$oCsv = Import-Csv $SalesforceCsv
If (!($Users)){
$users = get-content c:/scripts/ChatterUsers.txt
$array = $true
}
else
{
$Users = $User.trim()
}
$users | % {
Check-ChatterUser $oCsv $_
}
Do {
$Users = ""
If ($Users.trim() -eq ""){
exit #Script =$true
}else{
$users | % {
Check-ChatterUser $oCsv $_
}
}
}until(exit) #Script -eq $true)
#EndRegion Main body
have you looked at the command line parameters for powershell.exe?
Are you sure you don't have a '-noexit' parameter in your command line for powershell.exe?
So turns out this is a querk with the .Exec command. The solution is to run a wrapper script i created in order to resolve the issue.
VBScript
dim objFSO, objShell, StrChatterCommand,strText, objTextFile, strLine
set objFSO = CreateObject("Scripting.FileSystemObject")
Const fsoForWriting = 2
Dim strUser
dim UserArray
Dim strMessage
strUSer = InputBox("Enter the username you wish to test the chatter object for. if there is more than one please put a space between each.")
UserArray = Split(strUser)
for each x in UserArray
strMessage = strMessage & x & vbCrLf
next
Set objTextFile = objFSO.CreateTextFile("c:\scripts\ChatterUsers.txt", true)
objTextFile.Write (strMessage)
objTextFile.Close
Set objTextFile = Nothing
wscript.sleep 500
StrChatterCommand = "powershell.exe C:\Scripts\start_script.ps1"
Set objShell = CreateObject("WScript.Shell")
objShell.run strChatterCommand, 1, true
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile ("c:\scripts\OutputFile.txt", ForReading)
strText = ""
Do Until objTextFile.AtEndOfStream
strLine = objTextFile.Readline
strText = strText & strLine & VbCrLf
Loop
objTextFile.Close
wscript.echo strText
set objFSO = nothing
Set objShell = nothing
Set objTextFile = nothing
wscript.quit
1st powerhsell script:
powershell.exe c:\scripts\WSM_Check_Chatter.ps1 -ExecutionPolicy ByPass -NoLogo -File | Out-File c:\scripts\OutputFile.txt -Encoding ASCII -Width 50
2nd powershell script:
#Region Set Variables & Env
$SalesforceCsv = "\\some\path$\Platform_LiveExtract.csv"
$aOutput = #()
#EndRegion Set Variables & Env
#Region Functions
Function Install-ADcmdlets{
#Ensure Group Policy module is installed
if ((Get-Module | ? {$_.Name -eq "activedirectory"}) -eq $null){
$ErrorActionPreference = "stop"
Try{
import-module activedirectory
}Catch{
Write-Host "Please install the Active Directory powershell cmdlets. Exiting Script..."
exit
}
}
}
Function get-ChatterCsvDetails ($fCsv, $FedID){
$Return = ($fCsv | ? {$_.FEDERATIONIDENTIFIER -eq $FedID})
if (!($Return)){
Write-Host "No User Account found in Chatter..."
}else{
Write-Host "$FedID found in Chatter"
Write-Host (" - Chatter Account created: " + $Return.CREATEDDATE.subString(0,10))
Write-Host (" - Chatter Account last logon: " + $Return.LASTLOGINDATE.subString(0,10))
}
Return $Return
}
Function Pause-Script{
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
exit
}
Function Get-DomainFromDN ([string]$fDN){
[string]$fReturn = ""
[array]$fSplit = $fDN -split ",DC="
for([int]$i=1; $i -le ($fSplit.count -1); $i++){
$fReturn += ("." + $fSplit[$i])
}
return $fReturn.substring(1,($fReturn.length -1))
}
Function Check-ADObjectChatterReadiness ($fUser, $fCsv){
$fErrorsFound = $False
$fUserDomain = (Get-DomainFromDN $fUser.DistinguishedName)
Write-Host ("Checking object " + $fUserDomain + "\" + ($fUser.Samaccountname))
#Check Samid cases match FederationID
if ($fCsv){
If ($fUser.samaccountname -cne $fCsv.FEDERATIONIDENTIFIER){
Write-host ("ACTION: Users SamId is in the wrong case. Please change it to " + $fCsv.FEDERATIONIDENTIFIER)
$fErrorsFound = $True
}
}
#Check first Name not blank
if (!($fUser.GivenName)){
Write-host "ACTION: User's GivenName is blank"
$fErrorsFound = $True
}
#Check last name not blank
if (!($fUser.SN)){
Write-host "ACTION: User's Surname is blank"
$fErrorsFound = $True
}
#Check DisplayName is not blank
if (!($fUser.displayName)){
Write-host "ACTION: User's Display Name is blank"
$fErrorsFound = $True
}
#Check UPN is not blank
If (!($fUser.userprincipalName)){
Write-host "ACTION: User's UPN is blank"
$fErrorsFound = $True
}else{
#Check UPN for illegal characters
if ($fUser.userprincipalName.ToString().contains(" ")){
Write-host "ACTION: User's UPN contains a space"
$fErrorsFound = $True
}
}
#Check Email for space
if ($fUser.Mail){
if ($fUser.Mail.contains(" ")){
Write-host "ACTION: User's Email contains a space"
$fErrorsFound = $True
}
}
#Check User is in the correct OU
if ($fUserDomain -eq "bskyb.com"){
if ($fUser.DistinguishedName -notlike "*,OU=User Accounts,DC=bskyb,DC=com"){
write-host "ACTION: Bskyb User account is not in a supported OU"
$fErrorsFound = $True
}
}else{
if ($fUser.DistinguishedName -notlike "*,OU=User Accounts,DC=Ext,DC=bskyb,DC=com"){
write-host "ACTION: Ext User account is not in a supported OU"
$fErrorsFound = $True
}
}
#If chatter account doesn't exist, check user is a member of federation group
if (!($fCsv)){
if ($fUser.extensionattribute2)
{
write-host "ACTION: Clear the users ExtensionAttribute2 value.`nAttempting to clear attribute now..."
try{
Set-ADUser $fUser -clear Extensionattribute2 -Server $fUserDomain
Write-Host "ACTION: SUCCESS - Attribute value cleared... please get the user to retest."
}
catch{
Write-Host "ACTION: FAILED... please manually clear the attribute value."
}
$fErrorsFound = $True
}
}
else
{
if (!($fUser.extensionattribute2))
{
write-host "ACTION: Set the users ExtensionAttribute2 value.`nAttempting to set attribute now..."
try{
set-aduser $fUser -Add #{extensionAttribute2="ChatterUser"} -Server $fUserDomain
Write-Host "ACTION: SUCCESS - Attribute value set... please get the user to retest."
}
catch{
Write-Host "ACTION FAILED... please manually set the attribute value."
}
$fErrorsFound = $True
}
}
#Check account is enabled
If ($fUser.Enabled -eq $false){
write-host "ACTION: User account is disabled in Active Directory"
$fErrorsFound = $True
}
#Check account is not a member of Deactivated group
$fUser.MemberOf | % {
if ($_ -like "*APP-CHATTER-DEACTIVATED*"){
write-host "ACTION: User has been de-activated from Chatter. Please check with Chatter team."
$fErrorsFound = $True
}
}
#Check for errors
if ($fErrorsFound -eq $False){
Write-host "No issues found with Active Directory object"
}
}
Function Check-ChatterUser ($fCsv, $fSamid){
Write-Host `n"--------------------------------------------------"
Write-Host "------------ Checking account $fSamid ------------"
$fChatterIssues = ""
$fLdapFilter = ('(samaccountname=' + $fSamid + ')')
$fAdCmdletUser = (get-aduser -LDAPFilter $fLdapFilter -server bskyb.com:3268 -Properties givenName,sn,mail,displayName,memberof,ExtensionAttribute2)
if ($fAdCmdletUser){
# User/s found
$oChatterUser = get-ChatterCsvDetails $fCsv $_
if (($fAdCmdletUser.count) -and ($fAdCmdletUser.count -ge 2)){
# samid In both domains
$fAdCmdletUser | % {
Check-ADObjectChatterReadiness $_ $oChatterUser
}
}else{
# 1 User returned
Check-ADObjectChatterReadiness $fAdCmdletUser $oChatterUser
}
}else{
#No User found
Write-Host "No user with samaccoutname found in GC"
}
Write-Host "`n------ Complete ------"
}
#EndRegion Functions
#Region Main body
Install-ADcmdlets
$oCsv = Import-Csv $SalesforceCsv
If (!($Users)){
$users = get-content c:/scripts/ChatterUsers.txt
$array = $true
}
else
{
$Users = $User.trim()
}
$users | % {
Check-ChatterUser $oCsv $_
}
Do {
$Users = ""
If ($Users.trim() -eq ""){
exit #Script =$true
}else{
$users | % {
Check-ChatterUser $oCsv $_
}
}
}until(exit) #Script -eq $true)
#EndRegion Main body
You could always do a forced close using .NET in your powershell script.
Here's a couple of ways to cause that to happen:
[System.Environment]::Exit()
The above will cause the powershell.exe app to exit with a code of 0. There's a version of the Exit() method that accepts an integer parameter so you can exit with a specific exit code.
[System.Diagnostics.Process]::GetCurrentProcess().Kill()
This one is quite severe. It essentially calls TerminateProcess under the covers. No exit code, just immediate termination.

Delete local administrator account with delete() method ADSI with Powershell

I am writing a powershell script to manage our local administrator accounts using a csv file.
#variable to store the data in data.csv
$userobjects = Import-CSV C:-data.csv
function main-list{
Write-Host "--------------------------------------"
Write-Host "Windows Powershell Account Manager"
Write-Host "--------------------------------------"
Write-Host "1 - Change Name"
Write-Host "2 - Disabled Account"
Write-Host "3 - Delete User"
Write-Host "4 - Exit"
[int]$action = Read-Host "Enter the menu number from above"
if ($action -eq 1){change-name}
if ($action -eq 2){disable-account}
if ($action -eq 3){delete-user}
if ($action -eq 4){cls; break}
}
function change-name
{
foreach ($user in $userobjects)
{
#Assign the content to variables
$FileHostname = $user.Host
$FileAccount = $user.Account
$FileNewname = $user.Rename
$FileDisable = $user.Disable
$FileDelete = $user.Delete
# Rename
if (($user.Account -ne $user.Rename) -and ($user.Rename -ne '' ))
{
#Write-Host "old name :"$FileHostname"/"$FileAccount "-> new name :"$FileHostname"/"$FileNewname
$connection = $FileHostname+"/"+$FileAccount
$accName = [ADSI]("WinNT://$connection")
if ($accName.path -eq "WinNT://"+$connection+"")
{
$accName.psbase.Rename($FileNewname)
Write-Host "Account(s) renamed"
$user.Account = $user.Rename
}
else
{
Write-Host "Account name :"$connection "can't be found on the host"
}
$user.Account = $user.Rename
$userobjects | export-csv C:-data.csv -notype
}
}
Write-Host "--------------------------------------"
main-list
}
function disable-account
{
foreach ($user in $userobjects)
{
#Assign the content to variables
$FileHostname = $user.Host
$FileAccount = $user.Account
$FileNewname = $user.Rename
$FileDisable = $user.Disable
$FileDelete = $user.Delete
if ($user.Disable -eq 'yes')
{
$connection = $FileHostname+"/"+$FileAccount
$accName = [ADSI]("WinNT://"+$connection+"")
if ($accName.UserFlags -eq '515')
{
Write-Host "Account :"$connection "is already disabled"
}
else
{
$accName.description = "Account disabled"
$accName.UserFlags = 2
$accName.setinfo()
Write-Host "Account(s) disabled"$connection
}
}
}
Write-Host "--------------------------------------"
main-list
}
function delete-user
{
foreach ($user in $userobjects)
{
#Assign the content to variables
$FileHostname = $user.Host
$FileAccount = $user.Account
$FileNewname = $user.Rename
$FileDisable = $user.Disable
$FileDelete = $user.Delete
#Delete
if ($user.Delete -eq 'yes')
{
$connection = $FileHostname+"/"+$FileAccount
$accName = [ADSI]("WinNT://"+$connection+"")
$accName.delete("user",$accName.name)
#Write-Host $connection deleted
}
else
{
Write-Host "Account name :"$connection "can't be found on the host"
}
}
}
}
$userobjects | export-csv C:-\data.csv -notype
main-list
I don't really know why I have this message when I am trying to use the delete function : "Unknown name", it is like it doesn't find the local account to delete it but I am not sure. However, It works perfectly when I want to rename or disable accounts.
My data file looks like that
http://www.noelshack.com/2016-05-1454622367-capture.png
I will post the real message when I will be back to work tomorow.
Thank you for your help.
Quick skim... wouldn't this need to be used instead? I think your $accName.name would be using the machine name.
$accName.delete("user",$user.account)
You delete() the user from the computer, so your [adsi] object should bind to the computer and call Delete() on that instead:
# Just the machine name, nothing more:
$Machine = [ADSI]"WinNT://$FileHostname"
# Now delete the user account from the machine
$Machine.Delete('user',$FileAccount)

PowerShell Remove the last error

In my PowerShell script I try to do some error handling. However, I'm depending on an advanced function that uses the Try/Catch clauses. So once in a while the code block in the function fails and goes to the Catch clause after generating an error. At this point the variable $Error is filled with one error.
If I then consult within my script the variable $Error it tells me there's one record, which is correct. But I would like to know if it's possible to only delete the last error within the function in the Catch clause? So I can keep my $Error variable clear for the script errors.
The problem is within Get-ADTSProfileHC. I tried to delete the last error with $Error[0] | Remove-Item but it failed.
The function:
Function Get-ADusersHC {
[CmdletBinding(SupportsShouldProcess=$True)]
Param(
[Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true,Position=0)]
[String[]] $OU
)
Begin {
Function Get-ADOUNameHC {
$CanonicalName = $_.CanonicalName
[System.Collections.ArrayList]$Pieces = $CanonicalName.split(“/”)
$Pieces.Remove($Pieces[-1])
$OU = $Pieces -join '\'
$OU -replace ($Pieces[0],$Pieces[0].ToUpper())
}
Function Get-ADManagerDisplayNameHC {
$m = Get-ADObject -Identity $_.manager -Properties displayName,cn
if($m.ObjectClass -eq "user") { $m.displayName } Else{ $m.cn }
}
Function Get-ADTSProfileHC {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true,Position=0)]
[String] $DistinguishedName,
[parameter(Mandatory=$true,Position=1)]
[ValidateNotNullOrEmpty()]
[ValidateSet('UserProfile','AllowLogon','HomeDirectory','HomeDrive')]
[String]$Property
)
Begin {
$User = [ADSI]"LDAP://$DistinguishedName"
}
Process {
Try {
Switch ($Property) {
'AllowLogon' {if ($($User.psbase.InvokeGet('allowLogon')) -eq '1'){$True}else{$False}}
'HomeDirectory' {$User.psbase.InvokeGet('TerminalServicesHomeDirectory')}
'HomeDrive' {$User.psbase.InvokeGet('TerminalServicesHomeDrive')}
'UserProfile' {$User.psbase.InvokeGet('TerminalServicesProfilePath')}
}
}
Catch {
# When we receive an error, it means the field has never been used before and is blank
# this is due to an error in the AD (same problem with the Quest CmdLet), AllowLogon is
# always 'TRUE' but we don't set it because we can't read it sometimes so we write 'blanks'
Write-Output $null
}
}
}
}
Process {
Foreach ($_ in $OU) {
Write-Verbose "Function Get-HCADusersNoManager > OU: $_"
Write-Verbose "Function Get-HCADusersNoManager > Manager field empty"
Get-ADUser -SearchBase $_ -Filter 'SAMAccountName -eq "shenn"' -Properties * |
#Get-ADUser -SearchBase $_ -Filter * -Properties * |
Foreach {
$Properties = ([Ordered] #{
"Creation date" = $_.whenCreated;
"Display name" = $_.displayName;
"CN name" = $_.name;
"Last name" = $_.sn;
"First name" = $_.givenName;
"Logon name" = $_.sAMAccountName;
"Manager" = if($_.manager){Get-ADManagerDisplayNameHC};
"Employee ID" = $_.EmployeeID;
"HeidelbergcCement Billing ID" = $_.extensionAttribute8
"Type of account" = $_.employeeType;
"OU" = Get-ADOUNameHC;
"Notes" = $_.info -replace "`n"," ";
"E-mail" = $_.EmailAddress;
"Logon script" = $_.scriptPath;
"TS User Profile" = Get-ADTSProfileHC $_.DistinguishedName 'UserProfile';
"TS Home directory" = Get-ADTSProfileHC $_.DistinguishedName 'HomeDirectory';
"TS Home drive" = Get-ADTSProfileHC $_.DistinguishedName 'HomeDrive';
"TS Allow logon" = Get-ADTSProfileHC $_.DistinguishedName 'AllowLogon'
})
$Object = New-Object -TypeName PSObject -Property $Properties
Write-Output $Object
}
}
}
}
Two easy ways to do this:
$error.Remove($error[0])
$Error.RemoveAt(0)
Don't forget to check there is an error first.
$Error.Remove($error[$Error.Count-1])
If errors variable is empty, you will not get any exception
I hope it helps