Up until recently, I was familiar with the idea of client pulling down information from a database. A database requires updates, patching, and maintenance. Usually, I’d be the one doing all that care and feeding, additional to taking proper care of the client application. Recently I’ve been playing with api-ninjas.
API-ninjas requires a free account, and provides back to you an API key. Some of the things you can pull include:
Airline flight information
Cocktail recipes
Conversion of Currency
DNS lookup
Holidays
IP information
The list is quite exhaustive. An API is a great alternative to that pesky database maintenance above. Api-Ninja includes code on pulling the API’s in python, C#, ruby and so forth. However, it did not include anything about powershell.
Below, I’ve pasted code to get a random fact of the day:
$apikey = "###supersecretapikey###"
$params = @{
"Uri" = "https://api.api-ninjas.com/v1/facts?limit=1"
"method" = "get"
"headers" = @{"X-API-Key" = $apikey
}
Invoke-RestMethod @Params | fl
##Sample output##
fact : A sneeze zooms out of your mouth at over 600 m.p.h
To use or change this code, change the Uri paramenter above to the value given by api-ninjas. Examples include:
https://api.api-ninjas.com/v1/cocktail?name=$input #for taking input for cocktail recipes
https://api.api-ninjas.com/v1/iplookup?address=$IP #for taking input for IP address
In my Azure Tenant, I have a VM, a domain controller that hosts, well… my domain.
I only use it for testing, most recently I was doing some SSPR testing. I only turn it on occasionally for testing some powershell scripts, this password reset utility, and other things that only an on-premises Domain Controller can really do.
Over time, over about 2 weeks I didn’t need it and had this server sitting in a powered off state. When I did need it again, after powering it on, I realized I couldn’t login with my Domain Admin credentials. The error was that my password had expired, and I needed to reset it.
Okay, I’ll use my backup Domain Admin account to reset it. The problem was, the backup Domain Admin account was giving the same error.
Uh-oh.
My primary, and backup domain admin accounts to my one cloud controller that is not replicated anywhere are both locked out. Now what?
Luck has it, there’s as way to do this that’s fairly painless and actually quite simple.
Create a .ps1 file. The only contents it needs are one line:
Net user AD-Admin NewP@ssword!
Name it something relevant like “password_reset.ps1”
This HAS to be an account that’s active in your AD, and perferrably a Domain Admin account. The password can be whatever you want, as long as it fits your password domain policy.
2. Goto portal.azure.com -> Storage accounts -> any_of_your_storage_accounts ->containers (create one if you have to) -> upload. Upload the .ps1 file you created in step 1 above.
3. In portal.azure.com -> Virtual Machines -> Your_VM_DC -> Settings -> Extensions + Applications -> Add a Custom Script Extension
Browse to the storage container in step 2, point to the .ps1 file created in step 1
Let the deployment run
6. Log onto your DC VM in Azure with the credentials from step 1 above. RESET any or all your domain admin passwords that have that requirement.
7. Uninstall and delete that Custom script extension from step 3 for this VM. Otherwise, every time it boots it will reset the password for this one user.
Delete that .ps1 file from the storage container too!
If you’re like me, you built a new AD for testing. And if you’re also like me, you imported a whole bunch of users into your AD. Some of those users likely had passwords that didn’t quite meet the domain criteria. If that happened, that means those users are disabled.
In past posts, I wrote about moving users into a different OU. Now, we’re going to change passwords for these users so we can enable them later.
For this, you’ll need a CSV in this format below. I took some liberties and retrieved a large amount of random passwords from manytools.org. There are many websites that can do this, I just like the format that manytools provided. I just pasted the passwords into the second column, the first column being the sAMAccountname of the user.
sAMAccountName
Password
Zuzana.Burris
gz9DndwkBh8s
Zandra.Caig
9eC3bcJ2SzA5
PowerShell code:
Import-Module Active Directory
$Resetpassword = Import-Csv "C:\path_to_username_password_file.csv"
#Store CSV file into $Resetpassword variable
foreach ($User in $Resetpassword) {
#For each name or account in the CSV file $Resetpassword, reset the password with the Set-ADAccountPassword string below
$User.sAMAccountName
$User.Password
Set-ADAccountPassword -Identity $User.sAMAccountName -Reset -NewPassword (ConvertTo-SecureString $User.Password -AsPlainText -force)
}
Write-Host " Passwords changed "
$total = ($Resetpassword).count
$total
Write-Host "Accounts passwords have been reset..."
Showing the Results
Once we’ve set the passwords, we need a way of knowing when or if the passwords were last set for a user. Referring back to the Get-ADuser cmdlet, we can look at the -passwordlastset property.
What are the situations you’ll need lots of Dummy AD data? When you want to run some awesomely crafted PowerShell AD scripts, that’s where.
I was in a situation a few months ago where I needed replicate a VERY large set of AD data in order to pull some queries with Get-Aduser and Set-Aduser. I toyed with the idea of just creating them manually, or restoring them from production (this is a bad idea, don’t restore from production for a testing environment!). So I found a script that would import a great deal of AD data, and I also found a place online that can create a buttload of fake AD data for me.
For this entry, I’m going to fill as many fields as possible that relate to a powershell script. For each field in powershell, we’ll create a matching one in Mockaroo, and we’ll name it consistently.
This is the set of data with parameters I’m using:
The fields I’m using in AD are (copied from above)
City
Company
Description
Department
Email
EmployeeID
GivenName
MobilePhone
Office
OfficePhone
Password
Path
Postalcode
State
Streetaddress
Surname
Title
I also need to place these created accounts into a specific OU. I had to do some editing in Excel, and placed the OU ADSI path into that Path attribute above.
Here’s my example with column and headers:
City
Company
Department
Email
EmployeeID
GivenName
MobilePhone
Office
OfficePhone
Password
Path
Postalcode
State
StreetAddress
SurName
Title
Ipaba
Skyble
Human Resources
cyouthead0@google.es
873-02-1259
Codie
+55 283 153 2678
592-719-1607
MhyWOJIAE
“OU=Contoso-Users,DC=Contoso,DC=com”
35198-000
787 Arizona Trail
Youthead
Structural Analysis Engineer
Generate the data you need, or create the information you require and save it into a CSV file (ideally in a Windows format).
Now, the powershell code:
01 # Import active directory module for running AD cmdlets
02 Import-Module activedirectory
03
04 #Store the data from ADUsers.csv in the $ADUsers variable
05 $ADUsers = Import-csv "C:\Users\Administrator\Desktop\2AD_users.csv"
06
07 #Loop through each row containing user details in the CSV file
08 foreach ($User in $ADUsers)
09 {
10 #Read user data from each field in each row and assign the data to a variable as below
11 $City =$User.City
12 $Company =$User.Company
13 $Description =$User.Description
14 $Department =$User.Department
15 $Email =$User.Email
16 $Employeeid =$User.Employeeid
17 $GivenName =$User.GivenName
18 $MobilePhone =$User.MobilePhone
19 $Office =$User.Office
20 $OfficePhone =$User.OfficePhone
21 $Password =$User.Password
22 $Path =$User.Path
23 $Postalcode =$User.Postalcode
24 $State =$User.State
25 $Streetaddress =$User.Streetaddress
26 $SurName =$User.SurName
27 $Title =$User.Title
28 $Username =$GivenName+"."+$Surname
29
30 #Check to see if the user already exists in AD
31 if (Get-ADUser -F {SamAccountName -eq $Username})
32 { #If user does exist, give a warning
33 Write-Warning "A user account with username $Username already exist in AD."
34 }
35 else
36 {
37 #User does not exist then proceed to create the new user account
38 #Account will be created in the OU provided by the $Path variable read from the CSV file
39 New-ADUser `
40 -City $City `
41 -Company $Company `
42 -Description $Description `
43 -Department $Department `
44 -Email $Email `
45 -EmployeeID $EmployeeID `
46 -GivenName $GivenName `
47 -MobilePhone $MobilePhone `
48 -Office $Office `
49 -OfficePhone $OfficePhone `
50 -AccountPassword (convertto-securestring $Password -AsPlainText -Force) `
51 -Path $Path `
52 -Postalcode $Postalcode `
53 -State $State `
54 -Streetaddress $Streetaddress `
55 -SurName $SurName `
56 -Title $Title `
57 -SamAccountName $Username `
58 -UserPrincipalName "$Username@dtab.org" `
59 -Name "$GivenName $SurName" `
60 -DisplayName "$GivenName $SurName" `
61 -Enabled $true
62 }
63 }
I had to reference the New-ADUser powershell commandlet. A great deal of the switches came from this article. As you can see, I’ve also alphabetized the fields to make sorting a little easier.Notes about this script:
This code stores the CSV columns (headers) information for each user into $variables. I’ve kept the variable names the same as the CSV headers tokeep things simple. The last line, $username stores the firstname (period) lastname. Everyone will likely have a different standard for usernames, I just like this format since I don’t have to re-write code.
Code Syntax explanation – lines 31-33
1 if (Get-ADUser -F {SamAccountName -eq $Username})
2 { #If user does exist, give a warning
3 Write-Warning "A user account with username $Username already exist in AD."
Some error checking code. Checking for duplicate information in the imported CSV file.
The variables used in this script are considered ‘more than necessary’. The bare basic amount needed (I think) are username, password, first and last name. Anything you add or take away, requires some editing of the code, and the CSV file.
Notes about this Script:
For some reason the New-ADUser command does not allow the -country variable, it seems to fail each time. This is not a deal breaker for me, but for you it might be something worth investigating.
When importing passwords, use 10 characters at a minimum. Mockaroo only shows a password “between 6 to 12 chars”. By trial and error, I found manytools.org where I could generate the passwords necessary in the format I wanted, and copy/pasted them into my user CSV.
Should you feel hesitant about running this script, add “-Whatif” on the end of the Add-ADUser cmdlet line