Message in a bottle – The Box

Message in a bottle – The Box

This will seem dumb, but do you need a message box in your script? Normally no, but when you are using a script for an end-user, you might need it. So, let us take a look at how to do it real quick.

The Script

function Invoke-SHDMessageBox {
    [cmdletbinding()]
    param (
        [Parameter(HelpMessage = "Message Title", Mandatory = $true)][Alias('Title', 'header')][string]$MessageTitle,
        [Parameter(HelpMessage = "Message Body", Mandatory = $true)][Alias('Boby', 'Information')][string]$MessageBody,
        [Parameter(HelpMessage = "Message Buttons", Mandatory = $true)][Alias('Buttons')][validateset("YesNo", "YesNoCancel", "OK", "OKCancel")][string]$MessageButtons,
        [Parameter(HelpMessage = "Message Image", Mandatory = $true)][Alias('Image')][validateset("Asterisk", "Error", "Exclamation", "Hand", "Information", "None", "Question", "Stop", "Warning")][string]$Messagetype
    )
    Add-Type -AssemblyName PresentationCore, PresentationFramework
    $ButtonType = [System.Windows.MessageBoxButton]::$MessageButtons
    $MessageIcon = [System.Windows.MessageBoxImage]::$Messagetype
    $Results = [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $messageicon)
    Return $Results
}

The Breakdown

Lets break this guy down. First thing first, the parameters.

  • MessageTitle – What will be presented as the title of the message box.
  • MessageBody – The message itself.
  • MessageButtons – What types of buttons.
    • YesNo
    • YesNoCancel
    • OK
    • OKCancel
  • MessageType – The type of image will be presented.

All the parameters are mandatory. None can be passed by the pipeline. All are single strings instead of my normal list of strings. It’s far easier that way.

Next, we need to add the assembly for the box. These are PresentationCore and PresentationFramework.

Add-Type -AssemblyName PresentationCore, PresentationFramework

Next, we just add items to the variables we will be using. The input from the parameters and their validate set. For the buttons themselves we call upon the power of the assembly we added earlier. [System.Windows.*] In the button case, the * becomes MessageBoxButton.

    $ButtonType = [System.Windows.MessageBoxButton]::$MessageButtons

Then the message box image will be the same way, but with messageboximage.

$MessageIcon = [System.Windows.MessageBoxImage]::$Messagetype

Then we put it all together with the messagebox itself.

$Results = [System.Windows.MessageBox]::Show($MessageBody, $MessageTitle, $ButtonType, $messageicon)

The first part of the show is the body followed by the title, then followed by the buttons, and finally the image. Notice I pipe it into Results. I do this because we want to return those results.

Return $Results

That’s it! Once you return the results, you can test them with an if statement. Come back Monday for a ballon notification function.

Print to All printers!

Print to All printers!

Recently I came into a company where their printers were called printer 1, printer 2… and so on and so forth. It was amazing. No one knew which printer went where, and I was asked to make some kind of sense of it. Since I had the support of the people, why not print to all the printers with the printer names. Powershell can do this for you.

First thing first, you will need access to the print server to run this script from. The server will need PowerShell 5.1 or higher.

The Power of this script comes into play with Out-Printer. You will need the printer’s name and a message for that printer. Believe it or not, you can send multiple lines as a message too. Thus, you can create a nice message to print out. The next piece you will need is the Get-Printer command. The below script is a message I printed out at the company. It printed to every printer. of course, I had small trouble with non-physical machines.

Scripts


$Printers = get-Printer 
foreach ($Printer in $Printers) {
$Message = @"
Hello, I am trying to assign printers to computers. I need some information. Please read over this and send the results to <your Email Address>. 

1) Your name.
2) Your Computer name.
3) Your username, What you use to log into the computer with. 
4) This Printers name: $($Printer.name)

To find your computer name follow these instructions:
1) Right-Click the start menu.
2) Click system
3) under "Device Specifications" you will find the device name. Note that name and add it to the reply email. 

your email should look like the one below:

My Name: <Your Name>
Computername: <Your Computer name>
Username: <Your UserName>
Printer: $($Printer.name)

Thank you for your time in this matter. 
"@

    Out-Printer -Name "$($Printer.name)" -InputObject $Message
}

The Break Down

First we grab the printers with the Get-Printer Command.

$Printers = get-Printer 

Then we loop through the printers with a foreach loop. Inside that loop, we will do our work.

foreach ($Printer in $Printers) {}

Next, we create the message we want to print to each printer. We do this by doing a simple variable with what is called a here-string. Here-Strings are large strings that can contain special characters and much more. Oftentimes it’s Contained within @” some data “@. Notice that the $ still triggers variables, and you can still pull items out of variables by using the $($Var.info) options.

$Message = @"
Hello, I am trying to assign printers to computers. I need some information. Please read over this and send the results to <your Email Address>. 

1) Your name.
2) Your Computer name.
3) Your username, What you use to log into the computer with. 
4) This Printers name: $($Printer.name)

To find your computer name follow these instructions:
1) Right-Click the start menu.
2) Click system
3) under "Device Specifications" you will find the device name. Note that name and add it to the reply email. 

your email should look like the one below:

My Name: <Your Name>
Computername: <Your Computer name>
Username: <Your UserName>
Printer: $($Printer.name)

Thank you for your time in this matter. 
"@

Finally we push the information into the Out-Printer command. You will need the name of the printer you wish to print to and the message you want to print.

Out-Printer -Name "$($Printer.name)" -InputObject $Message

That’s it, nothing really much else after that. I hope you all can put this to good use.

Convert a Mac Address to a CIDR with Powershell

Convert a Mac Address to a CIDR with Powershell

Today, I needed to convert a mac address to a CIDR. The lesson I learned about this is to go back to the basics instead of looking around for a quick answer. So, to the basics first.

A mac address is a 4 octet number that represents a binary position. It ranges between 1 and 255. This means something like 255.255.255.0 is represented in binary as: 1111 1111 1111 1111 1111 1111 0000 0000

It’s easier to remember the 255 number instead of all those ones and zeros. However, what’s that CIDR? Well, what’s a CIDR? A CIDR represents the mac address and how many positions there are. If you count the number above, it turns into 24 1s and 8 0s. Thus the CIDR is 24. Very simple.

Now, how do you change 240.0.0.0 to a cidr? You can go to a chart and look or we can use PowerShell. The first thing we need to do is split up this string.

"240.0.0.0" -split '\.' 

We split the string up with a split command and tell it to split it up by the . item. We use an exit \ because the . is a special character for regex. Next, we loop through this list of octets with a foreach-object loop.

$Mask -split '\.' | ForEach-Object {
        
    }

Then we break down each octet into a binary number. We do this with a system.convert and tell it the number we bytes we want which is 2.

[System.Convert]::ToString($_, 2)

We then pad that information because sometimes 0s will produce more useless items.

([System.Convert]::ToString($_, 2).PadLeft(8, '0'))

The code above will give us the 1s and 0s of the binary number. Now we need to count the ones. We do this by converting the string to a char array with at .toochararray(). We search the string with a where-object for the number 1 and finally count it.

(([System.Convert]::ToString($_, 2).PadLeft(8, '0')).tochararray() | where-object { $_ -eq '1' } | measure-object).count

Now we need to add each item up. We do this by adding a variable before the loop set to 0 and then add the variable to the variable and the count. Finally, after the loop, display the information.

$Cidr = 0
    $Mask -split '\.' | ForEach-Object {
        $Cidr = $Cidr + (([System.Convert]::ToString($_, 2).PadLeft(8, '0')).tochararray() | where-object { $_ -eq '1' } | measure-object).count
    }
    $Cidr

That’s it yall! We count the number of 1s. That will give us our cidr count.

Script

Have fun with the script!

function ConvertFrom-SHDIPv4MaskToCidr {
    param (
        [string]$Mask
    )
    $Cidr = 0
    $Mask -split '\.' | ForEach-Object {
        $Cidr = $Cidr + (([System.Convert]::ToString($_, 2).PadLeft(8, '0')).tochararray() | where-object { $_ -eq '1' } | measure-object).count
    }
    $Cidr
}
1000 Faces

1000 Faces

Need 1000 or unique user photos for your lab? There is a great website for just such a thing. https://thispersondoesnotexist.com/image. Let’s break down some code to see how we can pull a few hundred pictures.

The first thing we need to know is how many we want. We are going to get 1000 faces for this example. Next, we need a safe location. Finally, we need an sleep time for the site to regenerate an image. Lets get started.

$StartCount..$FinishCount

the two . in this code allows you to loop through two values. Next we need to pipe this command into a foreach object loop.

$StartCount..$FinishCount | foreach-object {}

Inside the for each loop we start the real work. We are going to use the Invoke-WebRequest. Our URI is the site “https://thispersondoesnotexist.com/image” We will select where we want to save the file using the -outfile location. We are going to save it in the save location we choose earlier. We will put the name as the number you are currently using. Finally we will add a -disablekeepalive flag to stop the system from keeping the connection alive. We do this out of respect for the site.

Invoke-WebRequest -Uri $URL -OutFile "$SaveFolder\$_.jpg" -DisableKeepAlive

Next we need to do a sleep cycle. We do this because if we do a request after another request, we will get the same image. 7 Seconds seems to be the magic number. We do this with Start-Sleep -Seconds 7.

Start-Sleep -Seconds 7

That’s it, It’s a simple process. The Invoke-WebRequest will get the needed image and save it to your computer. The site will generate a new picture each time you reach out.

The Scripts

Here is the script below.

function Get-Faces {
    param (
        [int]$StartCount = 1,
        [int]$FinishCount = 1000,
        [int]$SecondsToSleep = 7,
        [string]$SaveFolder = "C:\Dpb\100000 Faces"
    )
    $URL = 'https://thispersondoesnotexist.com/image'
    $StartCount..$FinishCount | foreach-object {
        Invoke-WebRequest -Uri $URL -OutFile "$SaveFolder\$_.jpg" -DisableKeepAlive
         Start-Sleep -Seconds $SecondsToSleep
    }
}

Have fun with this little guy, just remember to be respectful of the sites you are pulling information from.