add random passwortgenerator in the same function - powershell

Is it possible to add a random password generator in this function?
Function Create-User([String] $Username, [String] $Name, [String] $Surname, [String] $OU, [String] $Group){
$User = Get-ADUser -Filter {sAMAccountName -eq $Username}
}

I added the $password variable inside of your function that you can use however you choose. The value stored in the variable is a secure string. If you need to provide the password value to the user, you can capture the value first by not piping into the ConvertTo-SecureString cmdlet.
Function Create-User([String] $Username, [String] $Name, [String] $Surname, [String] $OU, [String] $Group){
$password = ((33..126) | ForEach-Object {[char]$_} | get-random -count 20) -join "" | ConvertTo-SecureString -asplaintext -force
New-AdUser -accountpassword $password # You will need to add the rest of your parameters here
}
You can change the -count value to whatever meets your security policy requirements. The example above generates a 20 character password using random characters from the ASCII table positions 33 through 126. You are free to update that range however you see fit.

You could add a small function to generate a password.
Below code creates a password with a mixture of uppercase- and lowercase letters, digits and if you want that also symbols.
function New-Password {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[ValidatePattern("[0-9]")]
[int]$Length = 12,
[switch]$IncludeSymbols
)
$pw = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
if ($IncludeSymbols) {
$pw += "!$%^-_:;{}<>#&#]~"
}
return -join ([Char[]]$pw | Get-Random -Count $length)
}
Use in your Create-User function like this:
Function Create-User {
[CmdletBinding()]
param(
[String]$Username,
[String]$Name,
[String]$Surname,
[String]$OU
)
# call the New-Password function to get a plain text password.
$plainTextPassword = New-Password -Length 8
$securePassword = $plainTextPassword | ConvertTo-SecureString -AsPlainText -Force
# the New-AdUser cmdlet has many parameters. Best use splatting for these.
$splat = #{
SamAccountName = $Username
Name = $Name
Surname = $Surname
Path = $OU
AccountPassword = $securePassword
# add more parameters as you see fit here
# see https://learn.microsoft.com/en-us/powershell/module/addsadministration/new-aduser?view=win10-ps
}
New-AdUser #splat
# output the user and the generated password because you will not be able to retrieve this later..
[PSCustomObject]#{
User = $Username
Password = $plainTextPassword
}
}
Example:
Create-User -Username jdoe -Name 'John Doe' -Surname Doe -OU 'OU=Users, OU=DepartmentX, DC=yourdomain, DC=com'
will output
User Password
---- --------
jdoe 4Wvhud02

Related

Powershell Set-ADAccountPassword for each user in a list

I have a function that generates a randomized password. I would ultimately like to import a list of usernames and then have that function run for each name while setting the password.
Function New-Password {
$Password = $null
Get-RandomCharacters
Scramble-String
Write-Host "$Password"
}
New-Password
$Password
How can I merge the $Password with
Set-ADAccountPassword -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "$Password" -Force)
You could add a switch to your function to convert it if necessary. Your full function would include something below with a reference to your other custom functions:
function Get-RandomCharacters {...}
function Scramble-String {...}
function New-Password {
[CmdletBinding()]
param(
[switch]$converttoSS
)
$Password = $null
$password = Get-RandomCharacters -length 10 -characters 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!"ยง$%&/()=?}][{##*+'
#Write-Host ('{0}' -f $Password)
if ($converttoSS.IsPresent) {
$password = ConvertTo-SecureString -String $password -AsPlainText -Force
$password
}
else {
$password
}
}
Where New-Password -converttoSS should return System.Security.SecureString.
But I think there's an easier way to do this with the System.Web assembly.
Function New-Password {
[CmdletBinding()]
param(
[switch]$converttoSS
)
$password = $null
Add-Type -AssemblyName 'System.Web'
$password = [System.Web.Security.Membership]::GeneratePassword(20, 5)
if ($converttoSS.IsPresent) {
$newpass = ConvertTo-SecureString $password -AsPlainText -Force
Write-Warning ('The secure string is {0}' -f $password)
$output = $newpass
}
else {
Write-Warning ('The password is {0}' -f $password)
$output = $password
}
return $output
}
Using this test data:
id,first_name,last_name,email,manager
1,Kelcy,Dannel,kdannel0#phoca.cz,Kelcy Dannel
2,Vivia,O'Kynsillaghe,vokynsillaghe1#sun.com,Vivia O'Kynsillaghe
3,Valerie,Cartmell,vcartmell2#histats.com,Valerie Cartmell
4,Hilary,Checo,hcheco3#msu.edu,Hilary Checo
5,Sonya,Isacsson,sisacsson4#eepurl.com,Sonya Isacsson
You could use a script similar to the one below. Note - Please make sure you test this before using it in production.
Function New-Password {...}
$users = Import-Csv "C:\Downloads\MOCK_DATA.csv"
Foreach ($u in $users) {
$newpass = New-Password -converttoSS
Get-ADUser -Identity $user.email | Set-ADAccountPassword -Reset -NewPassword $newpass
Write-Verbose $newpass
}

Powershell Invoke-Expression A parameter cannot be found that matches parameter name = ""

Im trying to invoke a Ps script from antoher script. The scripts are both in the same path.
Also the script I'm trying to invoke takes 4 parameters.
Whem i execute that file from powershell with the parameters, then it works without errors.
But invoking it with the Invoke-Expression Command does not work.
Keep getting the error :
'A parameter cannot be found that matches parameter name'
Script with the Paramters :
param ([Parameter(Mandatory = $true)]
[string] $Samname,
[string] $Fullname,
[string] $Password,
[string] $Groups
)
$securePassword = ConvertTo-SecureString $Password -AsPlainText -Force
New-localuser -name $Samname -FullName $Fullname -password $securePassword -PasswordNeverExpires -UserMayNotChangePassword
#Add the User to the Groups
$localGroups = Get-LocalGroup
[string[]]$GroupArray = $Groups.Split(' ')
foreach ($localgroup in $localGroups){
foreach ($group in $GroupArray){
$group = $group.Replace(';', '')
if ($group.toString().Equals($localgroup.toString())){
Add-LocalGroupMember -Group $localgroup -Member $samname
}
}
}
Script with Invoke-Expression command :
$XmlDocument = 'C:\SomeFile\toPs\TmpUser.config'
[XML]$XmlFile = Get-Content $XmlDocument
[string] $Samname = $XmlFile.User.Username
[string] $Fullname = $XmlFile.User.Fullname
[string] $Password = $XmlFile.User.Password
[string] $Groups = $XmlFile.User.Groups
$script = ".\CreateUser.ps1"
Invoke-Expression $script "-Samname $Samname -Fullname $Fullname -Password $Password -Groups $Groups"
I'm not that sure if I'm using the params the right way, when I invoke the script.
Thanks for your help :)
It's hard to tell exactly what's tripping up Invoke-Expression without the full extent of the error message, but the good news is that you don't need Invoke-Expression at all!
Use the invocation operator (also known as the "call operator", &) instead, it natively supports parameter binding:
$XmlDocument = 'C:\SomeFile\toPs\TmpUser.config'
[XML]$XmlFile = Get-Content $XmlDocument
[string] $Samname = $XmlFile.User.Username
[string] $Fullname = $XmlFile.User.Fullname
[string] $Password = $XmlFile.User.Password
[string] $Groups = $XmlFile.User.Groups
$script = ".\CreateUser.ps1"
& $script -Samname $Samname -Fullname $Fullname -Password $Password -Groups $Groups

Powershell not recognizing boolean argument

I have the following PS script
param (
# FQDN or IP address of the Domain Controller
[Parameter(Mandatory=$True)]
[string]$ADaddress,
# Active directory domain name
# example: directory.local
[Parameter(Mandatory=$True)]
[string]$ADDomainName,
# Domain admin
# example: administrator#directory.local
[Parameter(Mandatory=$True)]
[string]$domainAdmin,
# Domain admin password
[Parameter(Mandatory=$True)]
[string]$domainAdminPassword,
# User to be added
# example: testUser
[Parameter (Mandatory=$True)]
[string]$newUsername,
# Password of th user to be added
# example: 1!2#4%6
[Parameter (Mandatory=$True)]
[string]$newPassword,
# SAM account name of the user to added
# example: testuser
[Parameter (Mandatory=$True)]
[string]$newSamAccountName,
# Display name of the user to added
# example: "Test user for test purposes"
[Parameter (Mandatory=$True)]
[string]$newUserDisplayName
)
$domainAdminSecurePassword = $domainAdminPassword | ConvertTo-SecureString -asPlainText -Force
$domainAdminCredential = New-Object System.Management.Automation.PSCredential($domainAdmin, $domainAdminSecurePassword)
$newUserSecurePassword = $newPassword | ConvertTo-SecureString -asPlainText -Force
$UPN= $newUsername+"#"+$ADDomainName
Invoke-Command -ComputerName $ADaddress -Credential $domainAdminCredential `
-ScriptBlock {`
param($newUsername, $newUserSecurePassword, $newSamAccountName, $newUserDisplayName, $UPN) `
new-aduser -name $newUsername -AccountPassword $newUserSecurePassword -Enabled $true -SamAccountName $newSamAccountName -DisplayName $newUserDisplayName -UserPrincipalName $UPN -PasswordNeverExpires $true`
} `
-ArgumentList $newUsername, $newUserSecurePassword, $newSamAccountName, $newUserDisplayName, $UPN
Tho problem I get when invoking this script is:
Cannot convert 'System.String' to the type 'System.Nullable`1[System.Boolean]' required by parameter 'PasswordNeverExpires'.
I tried passing 1 instead, passing [bool]$true but the result remains the same. I am new to PS and I'm lost here. Can anyone shine some light on what the problem may be?
Alright, I found what the problem was.
Changed:
-PasswordNeverExpires $true`
to
-PasswordNeverExpires $true `
(added a space after true)
replacing $true with a variable did it for me.
So this:
$command = 'New-CMApplicationDeployment -Name $Name -CollectionName $Col -OverrideServiceWindow $true -Comment $Com -AvailableDateTime $Adt -DeployAction Install -DeployPurpose Available -UserNotification DisplaySoftwareCenterOnly'
Invoke-Expression -Command "& $command"
became:
$t = $true
$command = 'New-CMApplicationDeployment -Name $Name -CollectionName $Col -OverrideServiceWindow $t -Comment $Com -AvailableDateTime $Adt -DeployAction Install -DeployPurpose Available -UserNotification DisplaySoftwareCenterOnly'
Invoke-Expression -Command "& $command"
Its dumb but it worked.

how to create ad user with some requirements in powershell?

I have to create adUser's. The password should be the first 6 characters of the ID card and the last name. I should divide the full name into first name and last name.
This is my script, but it did not work:
$Userslist = import-csv "C:\teacherslist.csv"
ForEach ($User in $Userslist){
$name = $User.FullName -split '\s+'
$firstName = $name[0]
$lastName = $name[1]
$pass = $User.IDcard.subString(0,6)+$lastName
New-ADUser -name $User.StaffID
-GivenName $FirstName
-Surname $LastName
-DisplayName $user.FullName
-AccountPassword (ConvertTo-SecureString $pass -AsPlainText -force)
-Path 'OU=Teacher,DC=school,DC=com'
-HomeDrive 'F:'
-changePasswordAtLogon $true
}
Ok, you are probably getting parsing issues with your arguments on different lines like that. I understand that it makes is easier to read, but PowerShell doesn't know that the next line contains another parameter for your New-ADUser cmdlet unless you put a backtick at the end of each line (must be the last character of the line).
If you want to keep your parameters organized like that a better way to do it is to assign them to a variable as a hashtable and then splat the hashtable as your parameters for New-ADUser.
ForEach ($User in $Userslist){
$name = $User.FullName -split '\s+'
$firstName = $name[0]
$lastName = $name[1]
$pass = $User.IDcard.subString(0,6)+$lastName
$Params = #{'name' = $User.StaffID;
'GivenName' = $FirstName;
'Surname' = $LastName;
'DisplayName' = $user.FullName;
'AccountPassword' = (ConvertTo-SecureString $pass -AsPlainText -force);
'Path' = 'OU=Teacher,DC=school,DC=com';
'HomeDrive' = 'F:';
'changePasswordAtLogon' = $true}
New-ADUser #Params
}

Testing if a user exist locally always return false

I'm trying to write a custom powershell script that will create a local user if no user exists with the specified name.
I have this script :
function Ensure-LocalUser
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string] $userName,
[Parameter(Mandatory=$true)]
[string] $passWord
)
process{
$objOu = [ADSI]"WinNT://${env:Computername}"
$localUsers = $objOu.Children | where {$_.SchemaClassName -eq 'user'} | Select {$_.name[0].ToString()}
if($localUsers -NotContains $userName)
{
$objUser = $objOU.Create("User", $userName)
$objUser.setpassword($password)
$objUser.SetInfo()
$objUser.description = "CMM Test user"
$objUser.SetInfo()
return $true
}
else
{
return $false
}
}
}
The part related to the creation of the user works, but my -NotContains verification always return false. This leads to a failing attempt to create a user because the user already exists. Using a debugger, I can see that $localusers actually contains the username I'm looking for.
How can I correct my script to reach my goal ?
Change this line
localUsers = $objOu.Children | where {$_.SchemaClassName -eq 'user'} | Select {$_.name[0].ToString()}
with
$localUsers = $objOu.Children | where {$_.SchemaClassName -eq 'user'} | % {$_.name[0].ToString()}
You're doing it wrong ;) You really want this (which will create an array of strings):
$ou.Children | where {$_.SchemaClassName -eq 'user'} | foreach {
$_.name[0].tostring() }
Your code is creating a custom object with a property called "$_.name[0].ToString()"
In PowerShell 5.1 (available in Windows 10) and later, there are two cmdlets we can use for checking the existence of a local user and creating a new local user: Get-LocalUser and New-LocalUser.
So we can rewrite the above function in a more compact way:
function Ensure-LocalUser
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string] $userName,
[Parameter(Mandatory=$true)]
[string] $passWord
)
process{
$out = Get-LocalUser -Name $userName -ErrorAction SilentlyContinue
if($out -eq $null)
{
$passEnc = ConvertTo-SecureString -String $passWord -AsPlainText -Force
New-LocalUser -Name $userName -Password $passEnc -AccountNeverExpires -PasswordNeverExpires
return $true
}
else
{
write-host ("User '"+ $userName + "' already exists")
return $false
}
}
}
then call the function like this:
Ensure-LocalUser "john" "p#ssw0rd"
I know I am late to the party, but here is an easy way to find local users and output their current state.
# Find User Account to change
$usercheck = Get-WmiObject Win32_UserAccount -Filter "LocalAccount='true' and Name='Administrator'"
if($usercheck.disabled -eq $false){write-host "Account has been found"}
elseif($usercheck.disabled -eq $true){write-host "Account has been found, but disabled"}
else{write-host "Account has not been found."}