Embed Files into Powershell Scripts

Embed Files into Powershell Scripts

Do you have a zip file or an msi file that you need to embed into a powershell script for deployment. This is a quick and simple way to do this. The method is pretty sound and works most of the time. The larger the file, the more troubles the system has converting and converting back, so small files works wonders for this method.

The first thing we are going to do is convert a file into a base 64 string. This is done through the command Get-Content and the system convert method. Powershell 7 recently changed the command for this method and we will cover that first.

Powershell 7 Command

The get content changed the encoding flag to asbytestream flag.

$Content = Get-Content -Path $Path -AsByteStream -raw

This command will read the data as raw byte data which is needed for the System convert method. The Powershell 5 method users Encoding and then you select your type which is byte.

Powershell 5

$Content = Get-Content -Path $Path -Encoding Byte

These commands reads the data as raw information that will be used for the system.convert to base 64 string method.

$base64 = [system.convert]::ToBase64String($content)

Now the Base64 contains something that looks like this:

"//4wADEAMAAwADAAMAAwADAAZAAwADgAYwA5AGQAZABmADAAMQAxADUAZAAxADEAMQA4AGMANwBhADAAMABjADAANABmAGMAMgA5ADcAZQBiADAAMQAwADAAMAAwADAAMABlADYAYQAyADMAOAA4ADIAOQA3ADIAOQBiADIANABhAGEAMAA0ADcAMQBjADEANQBjADcAYwAwAGQANQA4AGYAMAAwADAAMAAwADAAMAAwADAAMgAwADAAMAAwADAAMAAwADAAMAAwADAAMwA2ADYAMAAwADAAMABjADAAMAAwADAAMAAwADAAMQAwADAAMAAwADAAMAAwAGIAMQA5ADcAOAA5AGQAYgBmADkAMAAxADYANgA2ADEANQBlADgAMwAzAGQAOQAxADMANgA0ADEAYwBmAGIANAAwADAAMAAwADAAMAAwADAAMAA0ADgAMAAwADAAMAAwAGEAMAAw==

We take that information and Pipe it into the clip.exe to bring it to our clipboard.

$Base64 | clip.exe

Converting it back

Now we need to convert the string back to a file. To do that we are going to use the System.Convert from base 64 string.

$Object = [System.Convert]::FromBase64String("The crazy text")

Now we have an object of random-looking data like before. We need to write those bytes to a file we do that with the System.IO.File write all bytes method. We will need the outfile location. and the object we created earlier to complete this task.

[system.io.file]::WriteAllBytes($OutFile,$object)

This will create the file you embedded into your powershell script.

Use Case

Encrypted Passwords

Let’s secure a password file and key file inside our embedded script. First, we are going to create the key for out password file.

$key = New-Object byte[] 16
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
$key | Out-File C:\temp\TestPassword.key 

This is the content of our key file:

41
202
16
223
129
18
138
116
106
132
9
217
180
41
226
108

Now we have our key made it’s time to create the password file.

$Password = "lazyAppl351" | ConvertTo-SecureString -AsPlainText -Force 
$Password | ConvertFrom-SecureString -Key $Key | Out-File c:\temp\TestPassword.txt

This is what the Password file looks like on the inside:

76492d1116743f0423413b16050a5345MgB8ADkAMAA1AGYAaABaAC8ASAB3AG8AUQBQAGUAdwBKAHgAbwBJAFIAKwA5AHcAPQA9AHwAZQA2ADQAOQBiADMAMQA2AGEAYwBjADAANAA4AGUANQAxAGMAOAA2ADgAOABkADkAYgBmAGIANgBkAGUAMgAwADQAZQA3AGQAMgA2ADMAMQBiADQANQA4AGIAOAA1ADcAMABlADAAMQBhAGIAYgA4AGIAYQBhADEAOAA4ADMANAA=

Now we will embed these files into our script.

$KeyFile = Get-Content -Path C:\temp\TestPassword.key -Encoding Byte
$base64 = [system.convert]::ToBase64String($Keyfile)
$Base64 | clip.exe

This will convert the key file into a working string that we can convert later. This is what the information looks like:

NDENCjIwMg0KMTYNCjIyMw0KMTI5DQoxOA0KMTM4DQoxMTYNCjEwNg0KMTMyDQo5DQoyMTcNCjE4MA0KNDENCjIyNg0KMTA4DQo=

Now we will do the same thing for the password file.

$KeyFile = Get-Content -Path C:\temp\TestPassword.txt -Encoding Byte
$base64 = [system.convert]::ToBase64String($Keyfile)
$Base64 | clip.exe

This is what this looks like:

NzY0OTJkMTExNjc0M2YwNDIzNDEzYjE2MDUwYTUzNDVNZ0I4QURrQU1BQTFBR1lBYUFCYUFDOEFTQUIzQUc4QVVRQlFBR1VBZHdCS0FIZ0Fid0JKQUZJQUt3QTVBSGNBUFFBOUFId0FaUUEyQURRQU9RQmlBRE1BTVFBMkFHRUFZd0JqQURBQU5BQTRBR1VBTlFBeEFHTUFPQUEyQURnQU9BQmtBRGtBWWdCbUFHSUFOZ0JrQUdVQU1nQXdBRFFBWlFBM0FHUUFNZ0EyQURNQU1RQmlBRFFBTlFBNEFHSUFPQUExQURjQU1BQmxBREFBTVFCaEFHSUFZZ0E0QUdJQVlRQmhBREVBT0FBNEFETUFOQUE9DQo=

Now we build the script with these two pieces of information. We recreate the files from the script and then pull them in like before. Here is the key code:

$keyBase64 = "NDENCjIwMg0KMTYNCjIyMw0KMTI5DQoxOA0KMTM4DQoxMTYNCjEwNg0KMTMyDQo5DQoyMTcNCjE4MA0KNDENCjIyNg0KMTA4DQo="
$Object = [System.Convert]::FromBase64String($keyBase64)
[system.io.file]::WriteAllBytes('C:\temp\TestPassword.key',$object)

and here is the Password code:

$PassBase64 = "NzY0OTJkMTExNjc0M2YwNDIzNDEzYjE2MDUwYTUzNDVNZ0I4QURrQU1BQTFBR1lBYUFCYUFDOEFTQUIzQUc4QVVRQlFBR1VBZHdCS0FIZ0Fid0JKQUZJQUt3QTVBSGNBUFFBOUFId0FaUUEyQURRQU9RQmlBRE1BTVFBMkFHRUFZd0JqQURBQU5BQTRBR1VBTlFBeEFHTUFPQUEyQURnQU9BQmtBRGtBWWdCbUFHSUFOZ0JrQUdVQU1nQXdBRFFBWlFBM0FHUUFNZ0EyQURNQU1RQmlBRFFBTlFBNEFHSUFPQUExQURjQU1BQmxBREFBTVFCaEFHSUFZZ0E0QUdJQVlRQmhBREVBT0FBNEFETUFOQUE9DQo="
$Object = [System.Convert]::FromBase64String($PassBase64)
[system.io.file]::WriteAllBytes('C:\temp\TestPassword.txt',$object)

Now we have both files needed to receive our password, let’s convert that password using the key from before. We get the content of the .key file with get-content. Then we use it when we convert to secure string the password file. Pushing all that information into a new credential object for later use in something like a nextcloud download. Then we remove the files as we don’t want that password getting out there.

$Username = "BobTheUser"
$key = Get-Content 'C:\temp\TestPassword.Key'
$MyCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content 'c:\temp\TestPassword.txt' | ConvertTo-SecureString -Key $key)
remove-item c:\temp\TestPassword.txt
remove-item c:\temp\TestPassword.key

MSI file

Let’s say we need to embed an MSI file. For example, we have a custom Open DNS MSI that will auto setup the Umbrella client on an end user’s computer. The first thing we want to do is convert that msi file to the base 64 string like above.

$content = Get-Content -Path C:\Temp\CustomOpenDNS.msi -Encoding Bye
[system.Convert]::ToBase64String($Content) | clip.exe

Here we are using the powershell 5 code to convert the msi into a string and pushing it out to our clipboard. Now we need to place that information into the script. This is what the script would look like:

$Base64 = "PCFET0NUWVBFIGh0bWw+CjxodG1sIGNsYXNzPSJuZy1jc3AiIGRhdGEtcGxhY2Vob2xkZXItZm9jdXM9ImZhbHNlIiBsYW5nPSJlbiIgZGF0YS1sb2NhbGU9ImVuIiA+Cgk8aGVhZAogZGF0YS1yZXF1ZXN0dG9rZW49IkZPVkorSVltUkJucnoyNU4zZDZyclhIM0Y5c3NzK3BSOS9HaVN2WFBMZHc9OldLQjd0OHdRSzE2TWx5VVBsNy9ZM0R2T1dMWjk5dHBpcjRlYkxzS3RXTFU9Ij4KCQk8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CgkJPHRpdGxlPgoJCVJhbmRvbW5lc3MJCTwvdGl0bGU+CgkJPG1ldGEgaHR0cC1lcXVpdj0iWC1VQS1Db21wYXRpYmxlIiBjb250ZW50PSJJRT1lZGdlIj4KCQk8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCwgbWluaW11bS1zY2FsZT0xLjAiPgoJCQkJPG1ldGEgbmFtZT0iYXBwbGUtaXR1bmVzLWFwcCIgY29udGVudD0iYXBwLWlkPTExMjU0MjAxMDIiPgoJCQkJPG1ldGEgbmFtZT0idGhlbWUtY29sb3IiIGNvbnRlbnQ9IiMwMDIxMzMiPgoJCTxsaW5rIHJlbD0iaWNvbiIgaHJlZj0iL2luZGV4LnBocC9hcHBzL3RoZW1pbmcvZmF2aWNvbj92PTMiPgoJCTxsaW5rIHJlbD0iYXBwbGUtdG91Y2gtaWNvbiIgaHJlZj0iL2luZGV4LnBocC9hcHBzL3RoZW1pbmcvaWNvbj92PTMiPgoJCTxsaW5rIHJlbD0ibWFzay1pY29uIiBzaXplcz0iYW55IiBocmVmPSIvY29yZS9pbWcvZmF2aWNvbi1tYXNrLnN2ZyIgY29sb3I9IiMwMDIxMzMiPgoJCTxsaW5rIHJlbD0ibWFuaWZlc3QiIGhyZWY9Ii9pbmRleC5waHAvYXBwcy90aGVtaW5nL21hbmlmZXN0P3Y9MyI+CgkJPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSIvaW5kZXgucGhwL2Nzcy9jb3JlLzEzM2EtZDJjNi1zZXJ2ZXIuY3NzP3Y9YmUwYjQ2NTY1ZjcwNWM3YmYzNzQ0OTIxMmRmYWQxNzYtYjA3MTM1Y2MtMyI+CjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iL2luZGV4LnBocC9jc3MvY29yZS8xMzNhLWQyYzYtY3NzLXZhcmlhYmxlcy5jc3M/dj1iZTBiNDY1NjVmNzA1YzdiZjM3NDQ5MjEyZGZhZDE3Ni1iMDcxMzVjYy0zIj4KPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSIvYXBwcy9maWxlc19yaWdodGNsaWNrL2Nzcy9hcHAuY3NzP3Y9NDdjZDc2ZTQtMyI+CjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iL2luZGV4LnBocC9jc3MvdGV4dC8wNzBhLWQyYzYtaWNvbnMuY3NzP3Y9YmUwYjQ2NTY1ZjcwNWM3YmYzNzQ0OTIxMmRmYWQxNzYtYjA3MTM1Y2MtMyI+CjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iL2NvcmUvY3NzL2d1ZXN0LmNzcz92PWIwNzEzNWNjLTMiPgo8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Ii9jb3JlL2Nzcy9wdWJsaWNzaGFyZWF1dGguY3NzP3Y9YjA3MTM1Y2MtMyI+CjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iL2NvcmUvY3NzL2d1ZXN0LmNzcz92PWIwNzEzNWNjLTMiPgoJCTxzY3JpcHQgbm9uY2U9IlJrOVdTaXRKV1cxU1FtNXllakkxVGpOa05uSnlXRWd6UmpsemMzTXJjRkk1TDBkcFUzWllVRXhrZHowNlYwdENOM1E0ZDFGTE1UWk5iSGxWVUd3M0wxa3pSSFpQVjB4YU9UbDBjR2x5TkdWaVRITkxkRmRNVlQwPSIgZGVmZXIgc3JjPSIvaW5kZXgucGhwL2NvcmUvanMvb2MuanM/dj1iMDcxMzVjYyI+PC9zY3JpcHQ+CjxzY3JpcHQgbm9uY2U9IlJrOVdTaXRKV1cxU1FtNXllakkxVGpOa05uSnlXRWd6UmpsemMzTXJjRkk1TDBkcFUzWllVRXhrZHowNlYwdENOM1E0ZDFGTE1UWk5iSGxWVUd3M0wxa3pSSFpQVjB4YU9UbDBjR2x5TkdWaVRITkxkRmRNVlQwPSIgZGVmZXIgc3JjPSIvY29yZS9qcy9kaXN0L21haW4uanM/dj1iMDcxMzVjYy0zIj48L3NjcmlwdD4KPHNjcmlwdCBub25jZT0iUms5V1NpdEpXVzFTUW01eWVqSTFUak5rTm5KeVdFZ3pSamx6YzNNcmNGSTVMMGRwVTNaWVVFeGtkejA2VjB0Q04zUTRkMUZMTVRaTmJIbFZVR3czTDFrelJIWlBWMHhhT1RsMGNHbHlOR1ZpVEhOTGRGZE1WVDA9IiBkZWZlciBzcmM9Ii9jb3JlL2pzL2Rpc3QvZmlsZXNfZmlsZWluZm8uanM/dj1iMDcxMzVjYy0zIj48L3NjcmlwdD4KPHNjcmlwdCBub25jZT0iUms5V1NpdEpXVzFTUW01eWVqSTFUak5rTm5KeVdFZ3pSamx6YzNNcmNGSTVMMGRwVTNaWVVFeGtkejA2VjB0Q04zUTRkMUZMTVRaTmJIbFZVR3czTDFrelJIWlBWMHhhT1RsMGNHbHlOR1ZpVEhOTGRGZE1WVDA9IiBkZWZlciBzcmM9Ii9jb3JlL2pzL2Rpc3QvZmlsZXNfY2xpZW50LmpzP3Y9YjA3MTM1Y2MtMyI+PC9zY3JpcHQ+CjxzY3JpcHQgbm9uY2U9IlJrOVdTaXRKV1cxU1FtNXllakkxVGpOa05uSnlXRWd6UmpsemMzTXJjRkk1TDBkcFUzWllVRXhrZHowNlYwdENOM1E0ZDFGTE1UWk5iSGxWVUd3M0wxa3pSSFpQVjB4YU9UbDBjR2x5TkdWaVRITkxkRmRNVlQwPSIgZGVmZXIgc3JjPSIvaW5kZXgucGhwL2pzL2NvcmUvbWVyZ2VkLXRlbXBsYXRlLXByZXBlbmQuanM/dj1iMDcxMzVjYy0zIj48L3NjcmlwdD4KPHNjcmlwdCBub25jZT0iUms5V1NpdEpXVzFTUW01eWVqSTFUak5rTm5KeVdFZ3pSamx6YzNNcmNGSTVMMGRwVTNaWVVFeGtkejA2VjB0Q04zUTRkMUZMTVRaTmJIbFZVR3czTDFrelJIWlBWMHhhT1RsMGNHbHlOR1ZpVEhOTGRGZE1WVDA9IiBkZWZlciBzcmM9Ii9jb3JlL2pzL2JhY2tncm91bmRqb2JzLmpzP3Y9YjA3MTM1Y2MtMyI+PC9zY3JpcHQ+CjxzY3JpcHQgbm9uY2U9IlJrOVdTaXRKV1cxU1FtNXllakkxVGpOa05uSnlXRWd6UmpsemMzTXJjRkk1TDBkcFUzWllVRXhrZHowNlYwdENOM1E0ZDFGTE1UWk5iSGxWVUd3M0wxa3pSSFpQVjB4YU9UbDBjR2x5TkdWaVRITkxkRmRNVlQwPSIgZGVmZXIgc3JjPSIvYXBwcy9maWxlc19zaGFyaW5nL2pzL2Rpc3QvbWFpbi5qcz92PWIwNzEzNWNjLTMiPjwvc2NyaXB0Pgo8c2NyaXB0IG5vbmNlPSJSazlXU2l0SldXMVNRbTV5ZWpJMVRqTmtObkp5V0VnelJqbHpjM01yY0ZJNUwwZHBVM1pZVUV4a2R6MDZWMHRDTjNRNGQxRkxNVFpOYkhsVlVHdzNMMWt6UkhaUFYweGFPVGwwY0dseU5HVmlUSE5MZEZkTVZUMD0iIGRlZmVyIHNyYz0iL2FwcHMvZXB1YnJlYWRlci9qcy9wbHVnaW4uanM/dj1iMDcxMzVjYy0zIj48L3NjcmlwdD4KPHNjcmlwdCBub25jZT0iUms5V1NpdEpXVzFTUW01eWVqSTFUak5rTm5KeVdFZ3pSamx6YzNNcmNGSTVMMGRwVTNaWVVFeGtkejA2VjB0Q04zUTRkMUZMTVRaTmJIbFZVR3czTDFrelJIWlBWMHhhT1RsMGNHbHlOR1ZpVEhOTGRGZE1WVDA9IiBkZWZlciBzcmM9Ii9hcHBzL2ZpbGVzX3ZpZGVvcGxheWVyL2pzL21haW4uanM/dj1iMDcxMzVjYy0zIj48L3NjcmlwdD4KPHNjcmlwdCBub25jZT0iUms5V1NpdEpXVzFTUW01eWVqSTFUak5rTm5KeVdFZ3pSamx6YzNNcmNGSTVMMGRwVTNaWVVFeGtkejA2VjB0Q04zUTRkMUZMTVRaTmJIbFZVR3czTDFrelJIWlBWMHhhT1RsMGNHbHlOR1ZpVEhOTGRGZE1WVDA9IiBkZWZlciBzcmM9Ii9hcHBzL2ZpbGVzX3JpZ2h0Y2xpY2svanMvc2NyaXB0LmpzP3Y9YjA3MTM1Y2MtMyI+PC9zY3JpcHQ+CjxzY3JpcHQgbm9uY2U9IlJrOVdTaXRKV1cxU1FtNXllakkxVGpOa05uSnlXRWd6UmpsemMzTXJjRkk1TDBkcFUzWllVRXhrZHowNlYwdENOM1E0ZDFGTE1UWk5iSGxWVUd3M0wxa3pSSFpQVjB4YU9UbDBjR2x5TkdWaVRITkxkRmRNVlQwPSIgZGVmZXIgc3JjPSIvYXBwcy9maWxlc19yaWdodGNsaWNrL2pzL2ZpbGVzLmpzP3Y9YjA3MTM1Y2MtMyI+PC9zY3JpcHQ+CjxzY3JpcHQgbm9uY2U9IlJrOVdTaXRKV1cxU1FtNXllakkxVGpOa05uSnlXRWd6UmpsemMzTXJjRkk1TDBkcFUzWllVRXhrZHowNlYwdENOM1E0ZDFGTE1UWk5iSGxWVUd3M0wxa3pSSFpQVjB4YU9UbDBjR2x5TkdWaVRITkxkRmRNVlQwPSIgZGVmZXIgc3JjPSIvYXBwcy90ZXh0L2pzL3B1YmxpYy5qcz92PWIwNzEzNWNjLTMiPjwvc2NyaXB0Pgo8c2NyaXB0IG5vbmNlPSJSazlXU2l0SldXMVNRbTV5ZWpJMVRqTmtObkp5V0VnelJqbHpjM01yY0ZJNUwwZHBVM1pZVUV4a2R6MDZWMHRDTjNRNGQxRkxNVFpOYkhsVlVHdzNMMWt6UkhaUFYweGFPVGwwY0dseU5HVmlUSE5MZEZkTVZUMD0iIGRlZmVyIHNyYz0iL2FwcHMvdGhlbWluZy9qcy90aGVtaW5nLmpzP3Y9YjA3MTM1Y2MtMyI+PC9zY3JpcHQ+CjxzY3JpcHQgbm9uY2U9IlJrOVdTaXRKV1cxU1FtNXllakkxVGpOa05uSnlXRWd6UmpsemMzTXJjRkk1TDBkcFUzWllVRXhrZHowNlYwdENOM1E0ZDFGTE1UWk5iSGxWVUd3M0wxa3pSSFpQVjB4YU9UbDBjR2x5TkdWaVRITkxkRmRNVlQwPSIgZGVmZXIgc3JjPSIvY29yZS9qcy9wdWJsaWNzaGFyZWF1dGguanM/dj1iMDcxMzVjYy0zIj48L3NjcmlwdD4KCQk8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Ii9pbmRleC5waHAvY3NzL2ljb25zL2ljb25zLXZhcnMuY3NzP3Y9MTYyOTE3OTQyOSIvPjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgbWVkaWE9IihwcmVmZXJzLWNvbG9yLXNjaGVtZTogZGFyaykiIGhyZWY9Ii9pbmRleC5waHAvYXBwcy9hY2Nlc3NpYmlsaXR5L2Nzcy91c2VyLWE4MmZkOTVkYjEwZmYyNWRmYWQzOWYwNzM3MmViZTM3Ii8+PGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSIvaW5kZXgucGhwL2FwcHMvdGhlbWluZy9zdHlsZXM/dj0zIi8+PG1ldGEgbmFtZT0icm9ib3RzIiBjb250ZW50PSJub2luZGV4LCBub2ZvbGxvdyIvPgk8L2hlYWQ+Cgk8Ym9keSBpZD0iYm9keS1sb2dpbiI+CgkJPG5vc2NyaXB0PgoJPGRpdiBpZD0ibm9qYXZhc2NyaXB0Ij4KCQk8ZGl2PgoJCQlUaGlzIGFwcGxpY2F0aW9uIHJlcXVpcmVzIEphdmFTY3JpcHQgZm9yIGNvcnJlY3Qgb3BlcmF0aW9uLiBQbGVhc2UgPGEgaHJlZj0iaHR0cHM6Ly93d3cuZW5hYmxlLWphdmFzY3JpcHQuY29tLyIgdGFyZ2V0PSJfYmxhbmsiIHJlbD0ibm9yZWZlcnJlciBub29wZW5lciI+ZW5hYmxlIEphdmFTY3JpcHQ8L2E+IGFuZCByZWxvYWQgdGhlIHBhZ2UuCQk8L2Rpdj4KCTwvZGl2Pgo8L25vc2NyaXB0PgoJCQkJCTxpbnB1dCB0eXBlPSJoaWRkZW4iIGlkPSJpbml0aWFsLXN0YXRlLXRleHQtd29ya3NwYWNlX2F2YWlsYWJsZSIgdmFsdWU9ImRISjFaUT09Ij4KCQkJCQk8aW5wdXQgdHlwZT0iaGlkZGVuIiBpZD0iaW5pdGlhbC1zdGF0ZS1jb3JlLWNvbmZpZyIgdmFsdWU9ImV5SnpaWE56YVc5dVgyeHBabVYwYVcxbElqb3hORFF3TENKelpYTnphVzl1WDJ0bFpYQmhiR2wyWlNJNmRISjFaU3dpWVhWMGIxOXNiMmR2ZFhRaU9tWmhiSE5sTENKMlpYSnphVzl1SWpvaU1qRXVNQzR4TGpFaUxDSjJaWEp6YVc5dWMzUnlhVzVuSWpvaU1qRXVNQzR4SWl3aVpXNWhZbXhsWDJGMllYUmhjbk1pT25SeWRXVXNJbXh2YzNSZmNHRnpjM2R2Y21SZmJHbHVheUk2Ym5Wc2JDd2liVzlrVW1WM2NtbDBaVmR2Y210cGJtY2lPbVpoYkhObExDSnphR0Z5YVc1bkxtMWhlRUYxZEc5amIyMXdiR1YwWlZKbGMzVnNkSE1pT2pJMUxDSnphR0Z5YVc1bkxtMXBibE5sWVhKamFGTjBjbWx1WjB4bGJtZDBhQ0k2TUN3aVlteGhZMnRzYVhOMFgyWnBiR1Z6WDNKbFoyVjRJam9pWEZ3dUtIQmhjblI4Wm1sc1pYQmhjblFwSkNKOSI+CgkJCQkJPGlucHV0IHR5cGU9ImhpZGRlbiIgaWQ9ImluaXRpYWwtc3RhdGUtY29yZS1jYXBhYmlsaXRpZXMiIHZhbHVlPSJleUpqYjNKbElqcDdJbkJ2Ykd4cGJuUmxjblpoYkNJNk5qQXNJbmRsWW1SaGRpMXliMjkwSWpvaWNtVnRiM1JsTG5Cb2NGd3ZkMlZpWkdGMkluMHNJbUp5ZFhSbFptOXlZMlVpT25zaVpHVnNZWGtpT2pCOUxDSm1hV3hsY3lJNmV5SmlhV2RtYVd4bFkyaDFibXRwYm1jaU9uUnlkV1VzSW1Kc1lXTnJiR2x6ZEdWa1gyWnBiR1Z6SWpwYklpNW9kR0ZqWTJWemN5SmRMQ0prYVhKbFkzUkZaR2wwYVc1bklqcDdJblZ5YkNJNkltaDBkSEJ6T2x3dlhDOXlibVJoWkdoa2JXRnVMbU52YlZ3dmIyTnpYQzkyTWk1d2FIQmNMMkZ3Y0hOY0wyWnBiR1Z6WEM5aGNHbGNMM1l4WEM5a2FYSmxZM1JGWkdsMGFXNW5JaXdpWlhSaFp5STZJall5TWpaaVlUZzNNek0zTTJZMVpUY3pZVE5sWmpVd05ERXdOelV5TTJZM0luMHNJbU52YlcxbGJuUnpJanAwY25WbExDSjFibVJsYkdWMFpTSTZkSEoxWlN3aWRtVnljMmx2Ym1sdVp5STZkSEoxWlgwc0ltRmpkR2wyYVhSNUlqcDdJbUZ3YVhZeUlqcGJJbVpwYkhSbGNuTWlMQ0ptYVd4MFpYSnpMV0Z3YVNJc0luQnlaWFpwWlhkeklpd2ljbWxqYUMxemRISnBibWR6SWwxOUxDSnZZMjBpT25zaVpXNWhZbXhsWkNJNmRISjFaU3dpWVhCcFZtVnljMmx2YmlJNklqRXVNQzF3Y205d2IzTmhiREVpTENKbGJtUlFiMmx1ZENJNkltaDBkSEJ6T2x3dlhDOXlibVJoWkdoa2JXRnVMbU52YlZ3dmFXNWtaWGd1Y0dod1hDOXZZMjBpTENKeVpYTnZkWEpqWlZSNWNHVnpJanBiZXlKdVlXMWxJam9pWm1sc1pTSXNJbk5vWVhKbFZIbHdaWE1pT2xzaWRYTmxjaUlzSW1keWIzVndJbDBzSW5CeWIzUnZZMjlzY3lJNmV5SjNaV0prWVhZaU9pSmNMM0IxWW14cFl5NXdhSEJjTDNkbFltUmhkbHd2SW4xOVhYMHNJbVJoZGlJNmV5SmphSFZ1YTJsdVp5STZJakV1TUNKOUxDSm1kV3hzZEdWNGRITmxZWEpqYUNJNmV5SnlaVzF2ZEdVaU9uUnlkV1VzSW5CeWIzWnBaR1Z5Y3lJNlcxMTlMQ0p1YjNScFptbGpZWFJwYjI1eklqcDdJbTlqY3kxbGJtUndiMmx1ZEhNaU9sc2liR2x6ZENJc0ltZGxkQ0lzSW1SbGJHVjBaU0lzSW1SbGJHVjBaUzFoYkd3aUxDSnBZMjl1Y3lJc0luSnBZMmd0YzNSeWFXNW5jeUlzSW1GamRHbHZiaTEzWldJaUxDSjFjMlZ5TFhOMFlYUjFjeUpkTENKd2RYTm9JanBiSW1SbGRtbGpaWE1pTENKdlltcGxZM1F0WkdGMFlTSXNJbVJsYkdWMFpTSmRMQ0poWkcxcGJpMXViM1JwWm1sallYUnBiMjV6SWpwYkltOWpjeUlzSW1Oc2FTSmRmU3dpY0dGemMzZHZjbVJmY0c5c2FXTjVJanA3SW0xcGJreGxibWQwYUNJNk9Dd2laVzVtYjNKalpVNXZia052YlcxdmJsQmhjM04zYjNKa0lqcDBjblZsTENKbGJtWnZjbU5sVG5WdFpYSnBZME5vWVhKaFkzUmxjbk1pT21aaGJITmxMQ0psYm1admNtTmxVM0JsWTJsaGJFTm9ZWEpoWTNSbGNuTWlPbVpoYkhObExDSmxibVp2Y21ObFZYQndaWEpNYjNkbGNrTmhjMlVpT21aaGJITmxMQ0poY0draU9uc2laMlZ1WlhKaGRHVWlPaUpvZEhSd2N6cGNMMXd2Y201a1lXUm9aRzFoYmk1amIyMWNMMjlqYzF3dmRqSXVjR2h3WEM5aGNIQnpYQzl3WVhOemQyOXlaRjl3YjJ4cFkzbGNMMkZ3YVZ3dmRqRmNMMmRsYm1WeVlYUmxJaXdpZG1Gc2FXUmhkR1VpT2lKb2RIUndjenBjTDF3dmNtNWtZV1JvWkcxaGJpNWpiMjFjTDI5amMxd3Zkakl1Y0dod1hDOWhjSEJ6WEM5d1lYTnpkMjl5WkY5d2IyeHBZM2xjTDJGd2FWd3ZkakZjTDNaaGJHbGtZWFJsSW4xOUxDSndjbTkyYVhOcGIyNXBibWRmWVhCcElqcDdJblpsY25OcGIyNGlPaUl4TGpFeExqQWlMQ0pCWTJOdmRXNTBVSEp2Y0dWeWRIbFRZMjl3WlhOV1pYSnphVzl1SWpveUxDSkJZMk52ZFc1MFVISnZjR1Z5ZEhsVFkyOXdaWE5HWldSbGNtRjBhVzl1Ulc1aFlteGxaQ0k2ZEhKMVpYMHNJbVpwYkdWelgzTm9ZWEpwYm1jaU9uc2ljMmhoY21WaWVXMWhhV3dpT25zaVpXNWhZbXhsWkNJNmRISjFaU3dpZFhCc2IyRmtYMlpwYkdWelgyUnliM0FpT25zaVpXNWhZbXhsWkNJNmRISjFaWDBzSW5CaGMzTjNiM0prSWpwN0ltVnVZV0pzWldRaU9uUnlkV1VzSW1WdVptOXlZMlZrSWpwbVlXeHpaWDBzSW1WNGNHbHlaVjlrWVhSbElqcDdJbVZ1WVdKc1pXUWlPblJ5ZFdWOWZTd2lZWEJwWDJWdVlXSnNaV1FpT25SeWRXVXNJbkIxWW14cFl5STZleUpsYm1GaWJHVmtJanAwY25WbExDSndZWE56ZDI5eVpDSTZleUpsYm1admNtTmxaQ0k2Wm1Gc2MyVXNJbUZ6YTBadmNrOXdkR2x2Ym1Gc1VHRnpjM2R2Y21RaU9tWmhiSE5sZlN3aVpYaHdhWEpsWDJSaGRHVWlPbnNpWlc1aFlteGxaQ0k2Wm1Gc2MyVjlMQ0p0ZFd4MGFYQnNaVjlzYVc1cmN5STZkSEoxWlN3aVpYaHdhWEpsWDJSaGRHVmZhVzUwWlhKdVlXd2lPbnNpWlc1aFlteGxaQ0k2Wm1Gc2MyVjlMQ0p6Wlc1a1gyMWhhV3dpT21aaGJITmxMQ0oxY0d4dllXUWlPblJ5ZFdVc0luVndiRzloWkY5bWFXeGxjMTlrY205d0lqcDBjblZsZlN3aWNtVnphR0Z5YVc1bklqcDBjblZsTENKMWMyVnlJanA3SW5ObGJtUmZiV0ZwYkNJNlptRnNjMlVzSW1WNGNHbHlaVjlrWVhSbElqcDdJbVZ1WVdKc1pXUWlPblJ5ZFdWOWZTd2laM0p2ZFhCZmMyaGhjbWx1WnlJNmRISjFaU3dpWjNKdmRYQWlPbnNpWlc1aFlteGxaQ0k2ZEhKMVpTd2laWGh3YVhKbFgyUmhkR1VpT25zaVpXNWhZbXhsWkNJNmRISjFaWDE5TENKa1pXWmhkV3gwWDNCbGNtMXBjM05wYjI1eklqb3pNU3dpWm1Wa1pYSmhkR2x2YmlJNmV5SnZkWFJuYjJsdVp5STZkSEoxWlN3aWFXNWpiMjFwYm1jaU9uUnlkV1VzSW1WNGNHbHlaVjlrWVhSbElqcDdJbVZ1WVdKc1pXUWlPblJ5ZFdWOWZTd2ljMmhoY21WbElqcDdJbkYxWlhKNVgyeHZiMnQxY0Y5a1pXWmhkV3gwSWpwbVlXeHpaU3dpWVd4M1lYbHpYM05vYjNkZmRXNXBjWFZsSWpwMGNuVmxmWDBzSW5Sb1pXMXBibWNpT25zaWJtRnRaU0k2SWxKaGJtUnZiVzVsYzNNaUxDSjFjbXdpT2lKb2RIUndjenBjTDF3dmJtVjRkR05zYjNWa0xtTnZiU0lzSW5Oc2IyZGhiaUk2SWtKbGFHOXNaQ0JYYjNKc1pDQnZaaUIzWlhRZ2MyOWphM01pTENKamIyeHZjaUk2SWlNd01ESXhNek1pTENKamIyeHZjaTEwWlhoMElqb2lJMlptWm1abVppSXNJbU52Ykc5eUxXVnNaVzFsYm5RaU9pSWpNREF5TVRNeklpd2lZMjlzYjNJdFpXeGxiV1Z1ZEMxaWNtbG5hSFFpT2lJak1EQXlNVE16SWl3aVkyOXNiM0l0Wld4bGJXVnVkQzFrWVhKcklqb2lJelUxTlRVMU5TSXNJbXh2WjI4aU9pSm9kSFJ3Y3pwY0wxd3ZjbTVrWVdSb1pHMWhiaTVqYjIxY0wyTnZjbVZjTDJsdFoxd3ZiRzluYjF3dmJHOW5ieTV6ZG1jL2RqMHpJaXdpWW1GamEyZHliM1Z1WkNJNklpTXdNREl4TXpNaUxDSmlZV05yWjNKdmRXNWtMWEJzWVdsdUlqcDBjblZsTENKaVlXTnJaM0p2ZFc1a0xXUmxabUYxYkhRaU9uUnlkV1VzSW14dloyOW9aV0ZrWlhJaU9pSm9kSFJ3Y3pwY0wxd3ZjbTVrWVdSb1pHMWhiaTVqYjIxY0wyTnZjbVZjTDJsdFoxd3ZiRzluYjF3dmJHOW5ieTV6ZG1jL2RqMHpJaXdpWm1GMmFXTnZiaUk2SW1oMGRIQnpPbHd2WEM5eWJtUmhaR2hrYldGdUxtTnZiVnd2WTI5eVpWd3ZhVzFuWEM5c2IyZHZYQzlzYjJkdkxuTjJaejkyUFRNaWZTd2lkWE5sY2w5emRHRjBkWE1pT25zaVpXNWhZbXhsWkNJNmRISjFaU3dpYzNWd2NHOXlkSE5mWlcxdmFta2lPblJ5ZFdWOUxDSjNaV0YwYUdWeVgzTjBZWFIxY3lJNmV5SmxibUZpYkdWa0lqcDBjblZsZlgwPSI+CgkJCQkJPGlucHV0IHR5cGU9ImhpZGRlbiIgaWQ9ImluaXRpYWwtc3RhdGUtdGhlbWluZy1kYXRhIiB2YWx1ZT0iZXlKdVlXMWxJam9pVW1GdVpHOXRibVZ6Y3lJc0luVnliQ0k2SW1oMGRIQnpPbHd2WEM5dVpYaDBZMnh2ZFdRdVkyOXRJaXdpYzJ4dloyRnVJam9pUW1Wb2IyeGtJRmR2Y214a0lHOW1JSGRsZENCemIyTnJjeUlzSW1OdmJHOXlJam9pSXpBd01qRXpNeUlzSW1sdGNISnBiblJWY213aU9pSWlMQ0p3Y21sMllXTjVWWEpzSWpvaUlpd2lhVzUyWlhKMFpXUWlPbVpoYkhObExDSmpZV05vWlVKMWMzUmxjaUk2SWpNaWZRPT0iPgoJCQkJCTxpbnB1dCB0eXBlPSJoaWRkZW4iIGlkPSJpbml0aWFsLXN0YXRlLWFjY2Vzc2liaWxpdHktZGF0YSIgdmFsdWU9ImV5SjBhR1Z0WlNJNlptRnNjMlVzSW1ocFoyaGpiMjUwY21GemRDSTZabUZzYzJWOSI+CgkJCQk8ZGl2IGNsYXNzPSJ3cmFwcGVyIj4KCQkJPGRpdiBjbGFzcz0idi1hbGlnbiI+CgkJCQkJCQkJCTxoZWFkZXIgcm9sZT0iYmFubmVyIj4KCQkJCQkJPGRpdiBpZD0iaGVhZGVyIj4KCQkJCQkJCTxkaXYgY2xhc3M9ImxvZ28iPgoJCQkJCQkJCTxoMSBjbGFzcz0iaGlkZGVuLXZpc3VhbGx5Ij4KCQkJCQkJCQkJUmFuZG9tbmVzcwkJCQkJCQkJPC9oMT4KCQkJCQkJCQkJCQkJCQkJPC9kaXY+CgkJCQkJCTwvZGl2PgoJCQkJCTwvaGVhZGVyPgoJCQkJCQkJCTxtYWluPgoJCQkJCTxmb3JtIG1ldGhvZD0icG9zdCI+Cgk8ZmllbGRzZXQgY2xhc3M9Indhcm5pbmciPgoJCQkJCTxkaXYgY2xhc3M9Indhcm5pbmctaW5mbyI+VGhpcyBzaGFyZSBpcyBwYXNzd29yZC1wcm90ZWN0ZWQ8L2Rpdj4KCQkJCQkJPHA+CgkJCTxsYWJlbCBmb3I9InBhc3N3b3JkIiBjbGFzcz0iaW5maWVsZCI+UGFzc3dvcmQ8L2xhYmVsPgoJCQk8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJyZXF1ZXN0dG9rZW4iIHZhbHVlPSJGT1ZKK0lZbVJCbnJ6MjVOM2Q2cnJYSDNGOXNzcytwUjkvR2lTdlhQTGR3PTpXS0I3dDh3UUsxNk1seVVQbDcvWTNEdk9XTFo5OXRwaXI0ZWJMc0t0V0xVPSIgLz4KCQkJPGlucHV0IHR5cGU9InBhc3N3b3JkIiBuYW1lPSJwYXNzd29yZCIgaWQ9InBhc3N3b3JkIgoJCQkJcGxhY2Vob2xkZXI9IlBhc3N3b3JkIiB2YWx1ZT0iIgoJCQkJYXV0b2NvbXBsZXRlPSJuZXctcGFzc3dvcmQiIGF1dG9jYXBpdGFsaXplPSJvZmYiIGF1dG9jb3JyZWN0PSJvZmYiCgkJCQlhdXRvZm9jdXMgLz4KCQkJPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0ic2hhcmluZ1Rva2VuIiB2YWx1ZT0iNmZMbnFvdDZEcW02b1RYIiBpZD0ic2hhcmluZ1Rva2VuIj4KCQkJPGlucHV0IHR5cGU9InN1Ym1pdCIgaWQ9InBhc3N3b3JkLXN1Ym1pdCIgCgkJCQljbGFzcz0ic3ZnIGljb24tY29uZmlybSBpbnB1dC1idXR0b24taW5saW5lIiB2YWx1ZT0iIiBkaXNhYmxlZD0iZGlzYWJsZWQiIC8+CgkJPC9wPgoJPC9maWVsZHNldD4KPC9mb3JtPgoJCQkJPC9tYWluPgoJCQk8L2Rpdj4KCQk8L2Rpdj4KCQk8Zm9vdGVyIHJvbGU9ImNvbnRlbnRpbmZvIj4KCQkJPHAgY2xhc3M9ImluZm8iPgoJCQkJPGEgaHJlZj0iaHR0cHM6Ly9uZXh0Y2xvdWQuY29tIiB0YXJnZXQ9Il9ibGFuayIgcmVsPSJub3JlZmVycmVyIG5vb3BlbmVyIiBjbGFzcz0iZW50aXR5LW5hbWUiPlJhbmRvbW5lc3M8L2E+IOKAkyBCZWhvbGQgV29ybGQgb2Ygd2V0IHNvY2tzCQkJPC9wPgoJCTwvZm9vdGVyPgoJPC9ib2R5Pgo8L2h0bWw+Cg==
"
$Object = [System.Convert]::FromBase64String($Base64)
[system.io.file]::WriteAllBytes("C:\temp\test.msi",$object)
msiexec /i C:\temp\test.msi /qn /norestart

As you can see by the size of the base64 string, that seems like a large file. Surprisingly that’s only 11kb in size. The larger the file the more code will be present and the chances of buffer overload increases.

Scripts

What kind of person would I be without giving you a function or two to make life easier on you. Here are two functions. The first converts the item to base64 string and copies it to your clipboard. The second converts a base64 string to an object.

function convertto-base64 {
    [cmdletbinding()]
    param (
        [string]$Path
    )
    process {
        if ($PSVersionTable.PSVersion.Major -ge 7) {
            $Content = Get-Content -Path $Path -AsByteStream -raw
        } else {
            $Content = Get-Content -Path $Path -Encoding Byte
        }
        $base64 = [system.convert]::ToBase64String($content)
        $Base64 | clip.exe
    }
}

Here is the convert back to the object script. You will need the string and an out path.

function Convertfrom-base64 {
    [cmdletbinding()]
    param (
        [string]$Base64String,
        [string]$OutFile
    )
    process {
        $Object = [System.Convert]::FromBase64String($Base64String)
        [system.io.file]::WriteAllBytes($OutFile,$object)
    }
}
Log Public IP Changes

Log Public IP Changes

This little script logs public IP address changes. The original design was to email out. I’ll make sure to point out when and where to put that code. So the idea is simple. It checks to see if it’s public IP address has changed using an invoke-webrequest. If it has changed, it checks to see if a log has been made. If it has been made, it updates the log, if it hasn’t been made, it creates the log. Then when the IP address changes back, it backs up the logs and stops. Lets take a look at the script.

The Script

Param (
    [string]$IPAddress = "Your IP Address"
)  
$IP = (invoke-webrequest -Uri "http://ifconfig.me/ip" -UseBasicParsing).content
If (!(Test-Path C:\temp)) { New-Item -Path "c:\temp" -ItemType Directory }
if (!($IP -like "$IPAddress")) {
    if (!(Test-Path c:\temp\IPTrigger.log )) {

#Email Code Goes Here

        $Datetime = (Get-Date).ToString("yyyy-MM-dd_HH-mm")
        "Datetime,IP" > c:\temp\IPTrigger.log
        "$datetime,$IP" >> c:\temp\IPTrigger.log 
    }
    else {
        $Datetime = (Get-Date).ToString("yyyy-MM-dd_HH-mm")
        "$datetime,$IP" >> c:\temp\IPTrigger.log 
    }
}
else {
    if (Test-Path c:\temp\IPTrigger.log) {
        $Datetime = (Get-Date).ToString("yyyy-MM-dd_HH-mm")
        Copy-Item -Path c:\temp\IPTrigger.log -Destination "c:\temp\IPTrigger_$($datetime).log.bak"
        Remove-Item -Path  c:\temp\IPTrigger.log

#Email Code goes here with attachment of the log bak. 

    }
}

The Breakdown

We grab the IP address from the Paramters. This way you can have the script called Public-IPChecker -IPAddress Something from your task scheduler. After we get what the IP Address should be we get what It is with the Invoke-webrequest command.

$IP = (invoke-webrequest -Uri "http://ifconfig.me/ip" -UseBasicParsing).content

There are a hand full of sites that grabs the IP address for you. I personally like Ifconfig.me because it places the IP address as the content. Thus no sorting through the HTML to get the IP address.

Next we ask if it’s the IP address. Then we ask if the log has been made.

if (!($IP -like "$IPAddress")) {
    if (!(Test-Path c:\temp\IPTrigger.log )) {}
}

If it doesn’t exist, we create it by getting the DateTime into a file friendly format. and Piping that information into the log file along with the current IP address.

$Datetime = (Get-Date).ToString("yyyy-MM-dd_HH-mm")
"Datetime,IP" > c:\temp\IPTrigger.log
"$datetime,$IP" >> c:\temp\IPTrigger.log 

If it does exist, we just update the log file using the same code but this time we remove the “Datetime,IP” part.

$Datetime = (Get-Date).ToString("yyyy-MM-dd_HH-mm")
"$datetime,$IP" >> c:\temp\IPTrigger.log 

If the IP addresses do match then we test to see if the log file is there. If it is there we create a bak of the log file and remove the old one. This is when you can send an email saying it’s back up. If it doesn’t exist, we do nothing.

if (Test-Path c:\temp\IPTrigger.log) {
        $Datetime = (Get-Date).ToString("yyyy-MM-dd_HH-mm")
        Copy-Item -Path c:\temp\IPTrigger.log -Destination "c:\temp\IPTrigger_$($datetime).log.bak"
        Remove-Item -Path  c:\temp\IPTrigger.log
}

That’s the full script in a nutshell.

Next Cloud – Download Files

Next Cloud – Download Files

In the last blog, I talked about how to upload to your next cloud’s file drop, aka upload only, password-protected folder. This time we will go over how to download from a password-protected folder. Let’s go over how to share out a file with a secure password.

Password-Locked Single File

  1. Navigate to the file you wish to share out.
  2. Click on the file in question.
  3. Click the share link + symbol.
  4. Checkbox the “Password Protect”
  5. Enter a new secure password.
  6. Document the password!
  7. Click the Arrow to set the password
  8. click the Clipboard to copy the link.
  9. In another browser, navigate to the link to make sure it works.
Password Protected
After password

Now we have the File shared, it’s time to download it.

  1. The share ID
  2. The Share Password
  3. The URL of the nextcloud site.
  4. The file name/location of where you will save the file.

Now you have those pieces of information, you can start the process of creating the header. Let’s look at the Variables first.

$NextCloudURL = "https://cloud.bolding.us/"
$ShareID = "XXXxxxxXXxxXXxXX"
$SharePassword = "hotCXxxxx47"
$Filename = "jre-8u301-windows-i586.exe"

Now we have the variables, it’s time to build the headers for our invoke-restmethod.

$Header = @{
    "Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$($ShareID):$($SharePassword)"));
    "X-Requested-With"="XMLHttpRequest";
}

Just like in the last bl

The Authorization type is going to be basic. We are going to convert the shareid and the sharepassword into the UTF8 so our nextcloud can understand it. We want all that as a base 64. So we create the string with “$($ShareID):$($SharePassword)” and push that into our System.Text.Encoding UTF8. Using the method GetByes. All that is then put into the System.Convert base of 64 string, aka password.

Next, we tell the site what we are requesting, we are requesting the XML HTTP request. Next, we will create the URL that will be used by the rest method.

$URL = "$($NextCloudURL)public.php/webdav"

Now we create the invoke-restmethod to download the file in question.

Invoke-RestMethod -Uri $URL -Headers $Header -OutFile c:\temp\$Filename

The Script

$NextCloudURL = "https://cloud.bolding.us/"
$ShareID = "XXXxxxxXXxxXXxXX"
$SharePassword = "hotCXxxxx47"
$Filename = "jre-8u301-windows-i586.exe"
$Header = @{
    "Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$($ShareID):$($SharePassword)"));
    "X-Requested-With"="XMLHttpRequest";
}
$URL = "$($NextCloudURL)public.php/webdav"
Invoke-RestMethod -Uri $URL -Headers $Header -OutFile c:\temp\$Filename

Non-Password Locked Single File

Now that we covered password locked, it’s time to look at the non-password locked. This is a single line item. Like above, just don’t create a password. Copy the URL.

  1. Navigate to the file that you wish to share
  2. clickt he share icon
  3. Click the share link +
  4. Copy the Link

This is a single-line command. The copied item will be the URL/shareID. If you place a /download at the end, it will download accordingly. Nice right. Its even nicer with PowerShell.

The Script

Invoke-WebRequest -Uri "https://cloud.bolding.us/index.php/s/XxXXXXxxxxXXXxX/download" -OutFile c:\temp\somefile.pdf

That’s it! A simple invoke-webrequest. Now, let’s take it to a different level.

Download a single file from a shared Folder

If you share out a single folder, you can download the files directly from that folder if you know those file names, even if the file isn’t shared itself. Standard information is required. First, let’s make the shared folder.

  1. Navigate to the folder you wish to share out.
  2. Click the share icon.
  3. Click the Share Link +
  4. Click the 3 Dots.
  5. Click the Password Protect
  6. Enter a new password
  7. Document the new password
  8. Click the Arrow beside the password
  9. Click the clip board to copy the link

Here are the items you are going to need to setup this command.

  1. The URL of the next cloud
  2. The Share ID
  3. The Share Password
  4. The File name you are going to download.
  5. The filename/location where you will be downloading too.

Let’s setup the variables now.

$NextCloudURL = "https://cloud.bolding.us/"
$ShareID = "XxxXxXXXxXXxXXX"
$SharePassword = "xXxXxxxX"
$FileName = Java.exe
$Outfilepath = c:\temp\java.exe

Next, we build the header like we did above. I’ll skip the explaining this time.

$Header = @{
        "Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$($ShareID):$($SharePassword)"));
        "X-Requested-With"="XMLHttpRequest";
    }

The share this time is the folder. So we are authing to that folder. This is great because if you forget the password later, it’s in the script. Next, we grab the file using the invoke-restmethod.

Invoke-RestMethod -Method GET -Header $Header -uri "$($NextCloudURL)public.php/webdav/$($Filename)" -OutFile $Outfilepath

Notice at the end of the URL, the $($filename). This is the filename inside the share. So we are looking for that file to download. That’s all, take a look at the script.

The Script

$NextCloudURL = "https://cloud.bolding.us/"
$ShareID = "XxxXxXXXxXXxXXX"
$SharePassword = "xXxXxxxX"
$FileName = Java.exe
$Outfilepath = c:\temp\java.exe
$Header = @{
        "Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$($ShareID):$($SharePassword)"));
        "X-Requested-With"="XMLHttpRequest";
}
Invoke-RestMethod -Method GET -Header $Header -uri "$($NextCloudURL)public.php/webdav/$($Filename)" -OutFile $Outfilepath

There we go, that’s it yall. If you have any questions feel free to reach out.

Next Cloud – File Drop

Next Cloud – File Drop

I love my nextcloud. It is hosted at my house, and I can upload files from anywhere in the world. It’s very clean, and one of the most awesome features is the file drop. I use scripts to upload the results all the time to the file drop location on my next cloud. A file drop is an upload-only file location. This means the outside world can not see the files inside of it. Only I can do that. I can also password lock this file drop location so only those with the password can get into it. It’s pretty cool.

How to setup a File Drop

I am going to assume you have a nextcloud. Once you log in, click the + icon to create a folder. We will call it PFD for password file drop and click the arrow to create.

Create file drop

Now we will set up the sharing side with the password lock.

  1. Click the PFD folder to open the menu on the right hand side.
  2. Click the sharing icon
  3. Click the share link +.
  4. Click the three dots
  5. Radio check the File Drop (Upload Only)
  6. Check the Password Protect
  7. It will auto generate a password, It’s best to make your own.
  8. Document your password!
  9. Click the arrow to save the password
  10. Click the clip board to copy the link for your new share
  11. In a different browser test your link.
Before Password
After Password

Now you have a safe place for the files to go. It’s time to upload files via PowerShell. You will need a few items. First the URL of your site. example https:\\cloud.bolding.us. Next, you will need the shareID of the folder in question. That can be found in your URL at the end. Example

  1. The URL. For this example we will be using https://cloud.bolding.us
  2. The shareID of the directory in question. It is the last part of the main url that we copied by clicking the clip board. I have bolded it for you in this example: https://cloud.bolding.us/index.php/s/oWHeW4dfWnxwXXX
  3. Next you will need the password.

Those are the three things you will need to create your invoke-restmethod. Lets build the script. Lets declare our variables.

$NextCloudURL = "https://cloud.bolding.us/"
$ShareID = "oWHeW4dfWnxwXXX"
$SharePassword = "I'mAnAwesomePasswordDon'tYoVKnowThisRock$LikeCheesecake!"

Next, we need the item we are going to upload. We are going to use the Get-item command to grab that information.

$item = Get-Item c:\temp\upload\mycrazyideas.sqlite

Now the hard part. We need to create the header. This is where we will be placing the passwords and the type of information we are going to be accessing.

$Headers = @{
        "Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$($ShareID):$($SharePassword)"));
        "X-Requested-With"="XMLHttpRequest";
    }

The Authorization type is going to be basic. We are going to convert the shareid and the sharepassword into the UTF8 so our nextcloud can understand it. We want all that as a base 64. So we create the string with “$($ShareID):$($SharePassword)” and push that into our System.Text.Encoding UTF8. Using the method GetByes. All that is then put into the System.Convert base of 64 string, aka password.

Next, we tell the site what we are requesting, we are requesting the XML HTTP request. Next, we will create the URL that will be used by the rest method.

$URLBuild = "$($NextcloudUrl)/public.php/webdav/$($Item.Name)"

This is building a string for our URL for the rest method. It will look something like this:

  • https://cloud.bolding.us/public.php/webdav/mycrazyideas.sqlite

Now we have the Header that will be needed for our rest method. We have the URL. now we need the method and the file. We do the file by using the -InFile and select the full name of the file $Item.Fullname. The method will be PUT as we are putting something somewhere.

Invoke-RestMethod -Uri $URLBuild -InFile $Item.Fullname -Headers $Headers -Method Put 

Now it’s time to put it all together into a workable function.

Script

function Invoke-SHDUploadToNextCloud {
    [cmdletbinding()]
    param (
        [string]$NextCloudURL,
        [string]$ShareID,
        [string]$SharePassword,
        [string]$ItemPath
    )
    $item = Get-Item $ItemPath
    $Headers = @{
        "Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$($ShareID):$($SharePassword)"));
        "X-Requested-With"="XMLHttpRequest";
    }
    $URLBuild = "$($NextcloudUrl)/public.php/webdav/$($Item.Name)"
    Invoke-RestMethod -Uri $URLBuild -InFile $Item.Fullname -Headers $Headers -Method Put  
}
WSD Printers IP Address

WSD Printers IP Address

WSD is an awesome service for printers. It goes out and finds a printer on the network and adds it accordingly. It does all the IP address stuff for you. Which is awesome. It even tells you that it was set up as a wsd by naming the port wsd and some code. Super friendly. However… What happens when DHCP changes that IP address because someone forgot to do a reservation? How do you get that IP address? Believe it or not, that IP address is stored in the registry for the most part. Its located under the Hardware Local Machine > System > Current Control Set > Enum > SWD > DAFWSDProvider. Each entry has a friendly name and location information. The location information has the IP address like a web page. Powershell can give you this information pretty quickly with a single line as well. Let’s take a look.

Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Enum\SWD\DAFWSDProvider | foreach-object { $_ | Get-ItemProperty | Select-Object FriendlyName, LocationInformation }

Get-childitem is normally used in directories. The registry is a type of directory with files inside of it. So we use the get-childitem and treat the registry as a file path. We navigate to the DAFWSDProvider. Then we look at each file or in this case item property with Get-ItemProperty. We are looking for that FriendlyName and the LocationInformation. The location information will look like https://192.168.2.62/something because it is treating the IP address as a webpage. Still unsure why. The above command will list all of the printers like this. If it has an IP address, it will appear there.

Now we can wrap this up in a nice little function for remote computers.

The Script

function Get-SHDWDSPrinters {
    [cmdletbinding()]
    param (
        [string[]]$ComputerName = $Env:COMPUTERNAME
    )
    foreach ($Computer in $ComputerName) {
        Invoke-Command -ComputerName $Computer -ScriptBlock {
            Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Enum\SWD\DAFWSDProvider | foreach-object { $_ | Get-ItemProperty | Select-Object FriendlyName, LocationInformation }
        }
    }
}