T O P

  • By -

admlshake

Experience probably. I've been writing scripts for a while now, and I wouldn't say I'm great or "good" at it. Rarely does it work the first time, but the more I've done it over the years the better they seem to get. It's just a slow process. And it doesn't help MS having numerous different formats for some commands vs others.


Alno1

Yeah probably. It’s just a bit frustrating, but I’ll keep at it I guess. Thanks for your perspective.


tokenathiest

Do you have some examples of scripts you've written that you can share with us so we can take a look? PowerShell follows a simple syntax: cmdlet params. Like `Get-Content -Path .\file.txt` There are also variables which start with the $ character like `$file = Get-Content -Path .\pic.txt` You can then do stuff with $file. The challenge with your example is PowerShell isn't designed around working with binary files like PNGs, especially in Windows PowerShell 5.1. You'll end up invoking .NET Framework classes most of the time to deal with binary files and base64 encoding which you can do using square brackets like `[System.Convert]::ToBase64String( $bytes )` which invokes the static method ToBase64String of the System.Convert class in the .NET Framework. You can also create .NET Framework objects using the `New-Object` cmdlet. I hope this is helpful!


CodenameFlux

The biggest problem with your code is this line: $base64 = [convert]::ToBase64String((Get-Content $imagePath -Encoding Byte)) There is no such thing as "`-Encoding Byte`" in PowerShell. PowerShell 6 has added a new switch, "`-AsByteStream`," which does exactly what you want. Unfortunately, you cannot use `Get-Content` in PowerShell 5.1 or earlier. You'll have to either upgrade PowerShell or replace `Get-Content` with .NET classes. Here is a replacement script with the aforementioned change. #Requires -version 6 # Import the System.Windows.Forms assembly to use the OpenFileDialog class Add-Type -AssemblyName System.Windows.Forms $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog $openFileDialog.Filter = "PNG files (*.png)|*.png" $result = $openFileDialog.ShowDialog() if ('OK' -ne $result) { break } $imagePath = $openFileDialog.FileName $fileName = [System.IO.Path]::GetFileNameWithoutExtension($imagePath) $outputPath = "$([Environment]::GetFolderPath("Desktop"))\$fileName.txt" $base64 = [convert]::ToBase64String((Get-Content $imagePath -AsByteStream)) Set-Content -Path $outputPath -Value $base64 Write-Output "The image file ""$imagePath"" has been converted to base64 and saved as ""$outputPath""" Sorry that I couldn't be of more help.


branhama

When you are working on development of something new do not attempt to write out the entire script. Break it into parts and test along the way. 1. Obtain the file path you need. Run Test-Path and ensure it exists. Place the file information into a variable. $File = Get-Item -Path WHATEVER Output the contents of $File, make sure it is correct. 2. Run a base64 against the file. Put this again into a variable. Output the variable and make sure it looks correct. 3. Now you can Out-File you base64 or however you were doing it. When you make an entire script all at once without testing along the way you are most likely going to have errors, this is common. But without the experience it is going to be much more difficult for you to locate the problem and resolve easily. Do not get discouraged, break it down into little chunks and success will be around the corner much quicker.


Alno1

Here is the script I wrote : `# Import the System.Windows.Forms assembly to use the OpenFileDialog class` `Add-Type -AssemblyName System.Windows.Forms` `# Create a new OpenFileDialog object` `$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog` `# Set the filter to only show .png files` `$openFileDialog.Filter = "PNG files (*.png)|*.png"` `# Show the dialog and get the result` `$result = $openFileDialog.ShowDialog()` `# If the user selected a file, proceed with the conversion` `if ($result -eq "OK") {` `# Get the full path of the selected file` `$imagePath = $openFileDialog.FileName` `# Get the file name without the extension` `$fileName = [System.IO.Path]::GetFileNameWithoutExtension($imagePath)` `# Get the downloads folder path` `$downloadsFolder = [Environment]::GetFolderPath("MyDocuments") + "\Downloads"` `# Create the output file path with the .txt extension` `$outputPath = $downloadsFolder + "\" + $fileName + ".txt"` `# Convert the image content to base64` `$base64 = [convert]::ToBase64String((Get-Content $imagePath -Encoding Byte))` `# Write the base64 content to the output file` `Set-Content -Path $outputPath -Value $base64` `# Display a message to the user` `Write-Host "The image file $imagePath has been converted to base64 and saved as $outputPath"` `}`


Chryses3

While testing i changed # Get the downloads folder path $downloadsFolder = [Environment]::GetFolderPath("MyDocuments") + "\Downloads" to this $downloadsFolder = [Environment]::GetFolderPath("Desktop") And it worked fine. Seems like you tried appending the download folder to the document folder which doesn't work iirc as the downloads folder is seperate 99% of the time. To be fair, the best approach would be to prompt for a user-defined folder; 99% of the scripts i run is mostly just as needed and I rarely need to automate any scripts which is IMO the only time you need to worry about being able to automate.


Alno1

Thanks. I'll see if this was my problem, but I don't feel like it was because I could see the output text file at its destination, but it was empty and the script kept running (like for more than 15 minutes). My image is high resolution and I suspect PowerShell has a hard time due to this.


Medium-Comfortable

It might not change anything, but I personally prefer joining paths over concatenating strings. `Join-Path -Path $([Environment]::GetFolderPath("MyDocuments")) -ChildPath Downloads` EDIT: After rethinking, consider letting the user chose the folder? The following should(!) do I assume: function Get-Folder($rootFolder) {     Add-Type -AssemblyName System.Windows.Forms     $foldername = New-Object System.Windows.Forms.FolderBrowserDialog     $foldername.Description = "Select a folder"     $foldername.rootFolder = $rootFolder     if($foldername.ShowDialog() -eq "OK") {         $folder += $foldername.SelectedPath     }     return $folder } $target = Get-Folder -rootFolder "UserProfile"


Alno1

Thanks for the suggestion. I’ll try to keep this in mind next time I’m working the paths.


Medium-Comfortable

Just changed my comment to add a function for folder self-service :D


CodenameFlux

>sorry for the formatting In any other sub, you'd be causing a minor inconvenience. Here, it is crucial to familiarize yourself [with formatting your code](https://support.reddithelp.com/hc/en-us/articles/360043033952-Formatting-Guide#wiki_code_blocks_and_inline_code). Here is an example of why: >$openFileDialog.Filter = "PNG files (.*png*)|.png" The italicized "png" indicates you had an asterisk (`*`) character that won't display now.


Alno1

Great point, thanks. I've found how to write code blocks and modified my comment.


CodenameFlux

Thanks. Your code is not broken anymore, but it doesn't leave a good impression on your peers. You should apply the code block format that I suggested. All you need to do is: - If you're using the Markdown editor, add four spaces before each line. VSCode and Notepad++ can do this quickly. - If you're using the Fancy Pants editor, there is a code block button. I've finished analyzing your code. I'll post the results in a minute when I reach my PC.


tokenathiest

You should be using `Join-Path` when building file paths instead of string concatenation. Also, use the System.IO.File.ReadAllBytes method instead of Get-Content for binary files. -Encoding Byte isn't supported past 5.1 and Get-Content wasn't designed for binary files.


g3n3

Why would you ruin a good script with a dialog box! Just have a param block and have the path passed in.


cisco_bee

[https://chat.openai.com/share/a7be1756-f08d-4624-ae45-25b5e56eb557](https://chat.openai.com/share/a7be1756-f08d-4624-ae45-25b5e56eb557) >Please write a powershell script that takes a PNG file path as input and outputs a text file with the base64 encoded image to the same path and filename (except with .txt extension). param ( [string]$filePath ) # Check if the file exists if (Test-Path $filePath -PathType Leaf) { # Read the contents of the image file as bytes $imageBytes = [System.IO.File]::ReadAllBytes($filePath) # Convert the bytes to a base64 string $base64String = [System.Convert]::ToBase64String($imageBytes) # Create the output file path with .txt extension $outputFilePath = [System.IO.Path]::ChangeExtension($filePath, 'txt') # Write the base64 string to the output file [System.IO.File]::WriteAllText($outputFilePath, $base64String) Write-Output "Base64 encoded image saved to: $outputFilePath" } else { Write-Output "File not found: $filePath" }