This is a collection of scripts I've written to accomplish specific tasks.
PowerShell is fun to use!
# [Step] Get URL from Arguments
# The following is for mandatory arguments.
# URL is mandatory.
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[string]$bandcamp_url,
[Parameter(Mandatory=$true)]
[string]$short_story
)
# [Step] Get the html
# $html = curl $bandcamp_url
# You could use curl instead, but Invoke-WebRequest is already built in PS, so...
$html = Invoke-WebRequest -Uri $bandcamp_url
# If Invoke-WebRequest can't resolve the given URI, then halt the script.
# There must be a more elegant way of doing this.
if (!$html) {
Write-Output "[-] Couldn't resolve '$bandcamp_url'. Exiting..."
# Fake work, again...
Test-Connection -ComputerName localhost -Count 2 | Out-Null
return
}
# [Step] Get Album/Track title
# I can invoke innerText directly!
$album_title = $html.parsedHtml.getElementById("name-section").innerText
"[>] $album_title" | Write-Output
# [Step] Define constants
$file = "about.txt"
$delimiter = "======================================================================================="
$max_length = $delimiter.Length
$decor = "~~~~~~~~~~"
$header =
$delimiter +
"`n" +
$album_title +
"`n" +
$delimiter +
"`n"
$date = Get-Date
# Adjust the short story so it doesn't go past the length of the delimiter!
$adjusted_ss = ""
for ($c = 0; $c -lt $short_story.Length; $c++) {
if ($c % $max_length -eq 0 -and $c -gt 0) {
$adjusted_ss += "`n"
}
$adjusted_ss += $short_story[$c]
}
$short_story = $adjusted_ss
$footer =
$delimiter +
"`n" +
"Captured from ($bandcamp_url)" +
"`n" +
"by Brandon Hernandez using Powershell magic!" +
"`n" +
$date +
"`n" +
"$short_story" +
"`n" +
$delimiter
# [Step] Get Track List
$tracklist = $decor + "Track List" + $decor + "`n"
# $tracklist = $html.parsedHtml.getElementById("track_table")
# $raw_list = $html.parsedHtml.getElementsByClassName("title-col")
$raw_list = $html.parsedHtml.getElementsByClassName("track_row_view linked")
if ($raw_list.Length -eq 0) {
Write-Output "[-] No track list!"
} else {
Write-Output "[+] Track list found."
foreach ($item in $raw_list) {
$tracklist +=
$item.getElementsByClassName("track-number-col")[0].innerText + " " +
$item.getElementsByClassName("title-col")[0].innerText + "`n"
}
}
# [Step] Get album data
$about = $decor + "About" + $decor + "`n"
# I got this HTML class name from inspecting the HTML with Firefox's dev tools.
$album_data = $html.ParsedHtml.getElementsByClassName("tralbumData tralbum-about")
if ($album_data[0].Length -eq 0) {
Write-Output "[-] No album data!"
} else {
Write-Output "[+] Album data found."
}
# Index 0 is where all the contents are, although the array is size 1. Why is it an array, then?
# Try printing $album_data to see what I, Brandon of the past, mean.
# The day after: Oh! I get it! It is an array with all the found elements of the class!!!
$raw_about = $album_data[0].innerText
# Ok, so apparently, foreach loops are not "real" loops.
# Proof is "why" gets printed only once. Weird...
# $col = 0
# foreach($c in $raw_about) {
# $about += $c
# $col += 1
# Write-Output "why" # let's see how many times this gets printed.
# if ($col % 70 -eq 0) {
# $about += "`n"
# $col = 0
# }
# }
for ($c = 0; $c -lt $raw_about.Length; $c++) {
if ($c % $max_length -eq 0 -and $c -gt 0) {
$about += "`n"
}
$about += $raw_about[$c]
}
$about += "`n"
# [Step] Get album credits
$credits = $decor + "Credits" + $decor + "`n"
$album_credits = $html.ParsedHtml.getElementsByClassName("tralbumData tralbum-credits")
if ($album_credits[0].Length -eq 0) {
Write-Output "[-] No album credits!"
} else {
Write-Output "[+] Album credits found."
}
$raw_credits = $album_credits[0].innerText
for ($c = 0; $c -lt $raw_credits.Length; $c++) {
if ($c % $max_length -eq 0 -and $c -gt 0) {
$credits += "`n"
}
$credits += $raw_credits[$c]
}
$credits += "`n"
# [Step] Get album license
$license = $decor + "License" + $decor + "`n"
$license_raw = $html.parsedHtml.getElementById("license").innerText
if ($license_raw.Length -eq 0) {
Write-Output "[-] No album license!"
} else {
Write-Output "[+] Album license found."
}
$license += $license_raw + "`n"
# [Step] Get album tags!
$tags = $decor + "Tags" + $decor + "`n"
$tags_raw = $html.parsedHtml.getElementsByClassName("tag")
$tags_list = ""
if ($tags_raw.Length -eq 0) {
Write-Output "[-] No album tags!"
} else {
Write-Output "[+] Album tags found."
foreach ($tag in $tags_raw) {
$tags_list += $tag.innerHtml + "`n"
}
}
$tags += $tags_list
# [Step] Build the document
Write-Output "[!] Creating file..."
# Fake work with invisible ping lol
# ping localhost -n 2 | Out-Null
Test-Connection -ComputerName localhost -Count 2 | Out-Null
# Set-Content creates the file.
$header | Set-Content $file
# Add-Content appends to the file.
$tracklist | Add-Content $file
$about | Add-Content $file
$credits | Add-Content $file
$license | Add-Content $file
$tags | Add-Content $file
$footer | Add-Content $file
Write-Output "[+] File has been created successfully."
# This is a script to move all the wav files in a directory to the "wav" directory.
# The Get-ChildItem cmdlet returns a list of all the items in the current directory, including both files and directories.
# Element 0 is the only directory, the wav directory, so that's why the mv instruction moves the identified wav file into $items[0]
$items = Get-ChildItem
$len = $items.length
for ($i = 0; $i -lt $len; $i++) {
if ($items[$i].extension -eq ".wav") {
mv $items[$i] $items[0]
}
}
# Here is a more expressive version
$items = Get-ChildItem
$wav_dir = $items[0]
foreach ($item in $items) {
if ($item.extension -eq ".wav") {
mv $item $wav_dir
}
}
I wrote a script that creates a TCP server that serves data to an Ignition app via its TCP driver.
I divided the logic in 4 different stages.
The i-tcpDataLoop script can be used instead of c-tcpSendData.
From the PS terminal, I extract the contents of each script using Get-Content -Raw, and then I pipe it to Set-Clipboard.
After that, I just do CTRL+V and hit Enter.
If I need to make a little change to the code, I just do it directly in the terminal before hitting Enter.
If the change is significant, then I modify the script.
# TCP Server
# Listen to connections from any IP Address
# $ipAddress = [System.Net.IPAddress]::Parse("0.0.0.0");
$ipAddress = "0.0.0.0";
$port = 19991
$tcpListener = [System.Net.Sockets.TcpListener]::new($ipAddress, $port);
$tcpListener.Start();
# If Start() is successful, print Status.
Write-Output "[+] Server started on port $port. Waiting for connection..."
# Accept Client connection
# Execute only if $tcpListener has been created - run tcpServerInit.ps1
$client = $tcpListener.AcceptTcpClient();
# If connection to client is successful, print Status.
Write-Output "[+] Client connected!"
# Put data in Stream to be sent to the Client
$stream = $client.GetStream();
$message = "This is the data";
$data = [System.Text.Encoding]::ASCII.GetBytes($message);
$stream.Write($data, 0, $data.Length);
Write-Output "[+] Data sent."
#Send data loop
$stream = $client.GetStream();
for (;;) {
# Data frame to put data on
$data = New-Object byte[] 32;
# Maximum random 32-bit integer
$random_number = Get-Random -Minimum -2147483648 -Maximum 2147483647;
$rn_bytes = [System.BitConverter]::GetBytes($random_number);
$data[0] = $rn_bytes[0];
$data[1] = $rn_bytes[1];
$data[2] = $rn_bytes[2];
$data[3] = $rn_bytes[3];
$string = "Hello, data!";
$data[4] = $string[0]; #H
$data[5] = $string[1]; #e
$data[6] = $string[2]; #l
$data[7] = $string[3]; #l
$data[8] = $string[4]; #o
$data[9] = $string[5]; #,
$data[10] = $string[6]; #
$data[11] = $string[7]; #d
$data[12] = $string[8]; #a
$data[13] = $string[9]; #t
$data[14] = $string[10]; #a
$data[15] = $string[11]; #!
# Send a small random number
$small_random = Get-Random -Minimum -128 -Maximum 127;
$sr_bytes = [System.BitConverter]::GetBytes($small_random);
$data[16] = $sr_bytes[0];
$data[17] = $sr_bytes[1];
$data[18] = $sr_bytes[2];
$data[19] = $sr_bytes[3];
# Put Data frame in Stream and Write.
$stream.Write($data, 0, $data.Length);
Write-Output "[+] Random number: $random_number String: $string Small Random: $small_random"
Write-Output "Data sent!"
Start-Sleep -Milliseconds 2000;
}
# End all connections and shut down TCP server
$stream.Close();
$client.Close();
$tcpListener.Stop();
Write-Output "[+] TCP Server closed. Bye."
...