Dino Passwords!

Dino Passwords!

Passwords can be hard to make for people, especially kids and older users. That’s where Dino Passwords come into play. You can make simple and yet complex passwords using this service. This service also has a simple API to work with. I personally like using the API with new user creation scripts. The API is a single line with the invoke-webrequest command let.

Strong Passwords

(Invoke-WebRequest -Uri http://www.dinopass.com/password/strong).content

Simple Passwords

(Invoke-WebRequest -Uri http://www.dinopass.com/password/simple).content

That’s it, it’s as simple as that. Great little passwords that even kids can figure out how to use.

Disable Shared Mailbox Sign-Ins

Disable Shared Mailbox Sign-Ins

As part of the exchange online hardening process, one must disable the sign-in ability of shared mailboxes. This process is simple. You will need to exchange Online and the MS Online modules. First, we will grab all the shared mailboxes using the exchange online. Then using the user principal name, we grab the user info from MS Online module. From there we search for each MS user who isn’t blocked and set them to be blocked. Finally, we report back on the shared mailboxes that are blocked. Now we have the concept, let us break it down a little more. FYI, this can be done in a single line, but that would make it confusing. So, we will make it into a more functional script. Let us start up our VS code and get started.

First, connect to our need services with connect-exchangeonline and connect-msolservice. We live in the world of MFA, so I will assume you will complete the MFA process for these two commands.

Next, we will grab all the shared mailboxes by filtering the get-mailbox command. We are looking for the Recipient Type Details to be equal to the shared mailbox.

 $SharedMailboxes = Get-Mailbox -Filter { recipienttypedetails -eq "SharedMailbox" }

Then we will grab the MS user information from each Shared Mailbox. Once we get the MS user information we only want the user principal name and the block credential.

$Accounts = $SharedMailbox | Get-MsolUser | Select-Object userprincipalname, blockcredential

Now loop through the accounts checking each account to see if the credentials are blocked. If it isn’t, aka false, then we set the block credentials to true with set-MsolUser.

if ($Account.blockcredential -eq $False) {
     Set-MsolUser -UserPrincipalName $Account.Userprincipalname -BlockCredential $true        
 }

Next, we confirm every shared mailbox is set to true for blocking credentials. We are basically repeating the above command again as a single line. We use Get-Mailbox with the filter for the recipient type details to be equal shared mailbox. Pipe that into Get-MsolUser and then select the user principal name and block credentials.

Get-Mailbox -Filter { recipienttypedetails -eq "SharedMailbox" } | Get-MsolUser | Select-Object userprincipalname, blockcredential

Finally, we use our disconnects to disconnect from exchange and MS online. Let’s combine it all together and see how the script unfolds.

The Script

Connect-ExchangeOnline
Connect-MsolService
$SharedMailboxes = Get-Mailbox -Filter { recipienttypedetails -eq "SharedMailbox" }
Foreach ($SharedMailbox in $SharedMailboxes) {
     $Accounts = $SharedMailbox | Get-MsolUser | Select-Object userprincipalname, blockcredential
     foreach ($Account in $Accounts) {
          if ($Account.blockcredential -eq $False) {
                    Write-Host "Blocking $($Account.Userprincipalname)"
                    Set-MsolUser -UserPrincipalName $Account.Userprincipalname -BlockCredential $true        
          }
     }
}
Get-Mailbox -Filter { recipienttypedetails -eq "SharedMailbox" } | Get-MsolUser | Select-Object userprincipalname, blockcredential
        
Disconnect-ExchangeOnline
Get-PSSession | Remove-PSSession -Confirm:$false

Oneliner Password Generator

Oneliner Password Generator

Passwords, Passwords, and more Passwords. Let’s generate a 16 character password that is complex and random that you will have to save into your password manager because you will never remember it.

The Single Line

[string]::Join("",(1..16 | ForEach-Object {[char](Get-Random -Minimum 32 -Maximum 126)}))        

The Breakdown

Lets break it down and then make a function for easier use. We are going to use the concept of PEMDAS. For this breakdown.

Get-Random -Minimum 32 -Maximum 126

This gives us a random number between 32 and 126. Why is this important. The next part is why. We are grabbing a character of X, [char](x), These are considered password-safe characters of the ASCII set.

 1..16 | foreach-object {SomeCode}

This part repeats everything in the “some code” area 16 times. So we are grabbing 16 chars. Each loop occurs separately. This creates 16 characters that take up a different line on the shell prompt each time it runs. That’s where the next part comes into play.

[string]::Join("", array )

This part of the script is a string function that joins each part of the array together. Notice the “” part. This adds items inside the array. So if you want the password to have 7 every join, then place “7” here.

Now when you combine all this together. We create an array of random password-safe characters and join them all together. With their powers combined, we have a potential password.

Lets make a Function

function Get-SHDPassword {
    [cmdletbinding()]
    Param (
        [int]$Length = 16,
        [int]$Count = 1
    )
    for ($I=0;$I -lt $Count;$I++) {
        [string]::Join("",(1..$Length | ForEach-Object {[char](Get-Random -Minimum 32 -Maximum 126)}))        
    }
}

Here we added a count, so we can make more than one and choose from it. By default, we are setting them to 16 and to 1. This way we have a 16 character password that is done only once.

That’s all folks, let me know if you have any questions or corrections.

Dad Jokes

Dad Jokes

One of the things I love to do is add a Dad joke to my reports. Reddit has some good ones. What’s cool about Reddit is they have a JSON backend that can be used and Used I do.

The Function

Function Get-DadJoke {
    $DadJoke = Invoke-RestMethod -Uri "https://www.reddit.com/r/dadjokes/top.json" -UseBasicParsing
    $Joke = $DadJoke.data.children[(Get-Random -Minimum 0 -Maximum $($dadjoke.data.children.count - 1))]
    Write-Host "$($Joke.data.title)"
    Write-Host "$($Joke.data.selftext)"
}

The Breakdown

This script is super simple. We are using a rest method to grab the JSON information. Wrapping it in a function with a write-host. Nothing more simple.

$DadJoke = Invoke-RestMethod -Uri "https://www.reddit.com/r/dadjokes/top.json" -UseBasicParsing

The first part is the dad jokes themselves. We are grabbing the top jokes on the subreddit. We use the Invoke-RestMethod because we are grabbing that JSON.

$Joke = $DadJoke.data.children[(Get-Random -Minimum 0 -Maximum $($dadjoke.data.children.count - 1))]

The next line grabs a random Joke from the list. The $DadJoke.Data.Children are an array. We are grabbing a random index from the array where the minimum is 0. The maximum is the number of arrays minus one. We do a minus one because everything starts at 0.

Write-Host "$($Joke.data.title)"
    Write-Host "$($Joke.data.selftext)"

Finally, we write-host out the information. Notice once again, we use the $() structure. This way we can grab the subarrays of each item and displays the information accordingly.

A very simple breakdown of the function, and I hope you all enjoyed it.

Install Google Chrome with Powershell

Install Google Chrome with Powershell

My last weekly challenge to myself was to deploy google chrome with Powershell. This one was the hardest because it was hard to find the latest and greatest MSI 64 bit of google chrome. The coding wasn’t too hard after that. How google chrome works, follows suit the same way as firefox did.

The Script

$ChromeSource = "http://dl.google.com/tag/s/defaultbrowser/edgedl/chrome/install/GoogleChromeStandaloneEnterprise64.msi"
$Installer = "$ENV:TEMP\Google.msi"
Invoke-WebRequest -Uri $ChromeSource -OutFile $Installer
Get-Process -Name "Chrome" | Stop-Process -Force
msiexec /i $Installer /qn /norestart
Remove-Item $Installer

The Breakdown

We first start off getting the latest enterprise edition of google chrome. This is the 64-bit version thus the most stable version on them all. This is the version I would install everywhere in a company if I had a choice.

$ChromeSource = "http://dl.google.com/tag/s/defaultbrowser/edgedl/chrome/install/GoogleChromeStandaloneEnterprise64.msi"

Then we create the installer path and download the file using the Invoke-webrequest with the Outfile as the installer path.

$Installer = "$ENV:TEMP\Google.msi"
Invoke-WebRequest -Uri $ChromeSource -OutFile $Installer

Then we stop the google chrome process and install the latest version of google chrome using the msiexec command. Then we remove the installer.

Get-Process -Name "Chrome" | Stop-Process -Force
msiexec /i $Installer /qn /norestart
Remove-Item $Installer

That’s it. Very simple very straightforward. If you need to uninstall before installing (My testing was a success with overlapping the installers) then you can do the following before Installing google chrome:

$Chrome = Get-CimInstance win32_Product | where-object {$_.name -like "*Google*Chrome*"}
$Chrome | Invoke-CimMethod -MethodName Uninstall

Install Firefox with Powershell

Install Firefox with Powershell

Need to deploy the latest version of firefox to 1000 machines, Here is a little powerhouse script that can do just that. It’s similar to my last script (Gimp) as it downloads directly from the web. This time we don’t have to parse out a website since Modzilla has it laid out before us.

The Script

$FirefoxSource = "https://download.mozilla.org/?product=firefox-latest-ssl&os=win64&lang=en-US"
$Installer = "$ENV:TEMP\ModzillaFirefox.exe"
Invoke-WebRequest -Uri $FirefoxSource -OutFile $Installer
Get-Process -Name "*firefox*" | Stop-Process -Force
Start-Process -FilePath $Installer -ArgumentList "/s" -Verb runas -wait
Remove-Item $Installer

The Breakdown

The source is awesome. We are downloading directly from the site with their latest 64-bit product. This time we are going with the temporary file and then downloading the file with invoke-webrequest. Then we start the process of installing it with the /s flag which means silent. Since we are coming from the temp folder I threw in the runas flag to run it as the system. This way it installs for all users. Next, we set the wait flag to install the system. From everything I have read, we don’t need to uninstall the previous version to install the newest version. We do however have to stop the process that’s why we have a get process and stop process above. Finally, we remove the installer. That’s it. A lot simpler than Gimp.