PowerShell script to get files internal links

I raised a [complaint two days ago for a missing feature; a dialog window to insert files or internal links without opening the file explorer, copying the path, and converting it into a URI format.

While we wait for this feature to be released, I want to share a PowerShell script that performs this task. I will paste the script in my first reply.

Important: Before using the script, I highly recommend checking it with an AI chat assistant (like ChatGPT) for two main reasons:

  1. Understand the Steps and Process: This will help you know exactly how the script works and what it’s doing.
  2. Safety Revision: I haven’t explained the steps and process in detail in this post on purpose, At all events, it’s crucial to verify any script’s safety before running it on your system.

Thanks, and I hope this helps!

Add-Type -AssemblyName System.Windows.Forms

Select output directory for the .txt file

$folderDialog = New-Object System.Windows.Forms.FolderBrowserDialog
$folderDialog.Description = “Select output folder for the .txt file”

if ($folderDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
$outputFolder = $folderDialog.SelectedPath

# Generate unique output filename with incrementing number
$baseName = "SelectedFiles"
$counter = 0
do {
    $outputFile = Join-Path $outputFolder "$baseName$(if ($counter -eq 0) { '' } else { $counter }).txt"
    $counter++
} while (Test-Path $outputFile)

# Initialize collection for all selected files
$allSelectedFiles = [System.Collections.Generic.List[string]]::new()

# Loop for multi-folder file selection
do {
    $fileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $fileDialog.Multiselect = $true
    $fileDialog.Title = "Select files from ANY folder (Multiple allowed)"

    # Show file selection dialog
    $fileResult = $fileDialog.ShowDialog()
    
    if ($fileResult -eq [System.Windows.Forms.DialogResult]::OK) {
        $allSelectedFiles.AddRange($fileDialog.FileNames)
        
        # Create custom dialog with Continue/Finish buttons
        $actionDialog = New-Object System.Windows.Forms.Form
        $actionDialog.Text = "Action Required"
        $actionDialog.Size = New-Object System.Drawing.Size(320, 150)
        $actionDialog.StartPosition = "CenterParent"
        
        $label = New-Object System.Windows.Forms.Label
        $label.Text = "Do you want to continue selecting files or finish?"
        $label.Location = New-Object System.Drawing.Point(10, 20)
        $label.Size = New-Object System.Drawing.Size(280, 40)
        $actionDialog.Controls.Add($label)
        
        $btnContinue = New-Object System.Windows.Forms.Button
        $btnContinue.Text = "&Select More"  # Alt+S shortcut
        $btnContinue.Location = New-Object System.Drawing.Point(10, 70)
        $btnContinue.DialogResult = [System.Windows.Forms.DialogResult]::Yes
        $actionDialog.Controls.Add($btnContinue)
        
        $btnFinish = New-Object System.Windows.Forms.Button
        $btnFinish.Text = "&Finish"  # Alt+F shortcut
        $btnFinish.Location = New-Object System.Drawing.Point(140, 70)
        $btnFinish.DialogResult = [System.Windows.Forms.DialogResult]::No
        $actionDialog.Controls.Add($btnFinish)
        
        $actionDialog.AcceptButton = $btnContinue
        $actionDialog.CancelButton = $btnFinish
        
        # Show the action dialog
        $actionResult = $actionDialog.ShowDialog()
        
        if ($actionResult -eq [System.Windows.Forms.DialogResult]::No) {
            break # Exit loop if "Finish" is clicked
        }
    }
    else {
        break # Exit loop if "Cancel" is clicked in file dialog
    }
} while ($true)

# Save results with grouping and separators
if ($allSelectedFiles.Count -gt 0) {
    # Group files by extension
    $groupedFiles = $allSelectedFiles | Group-Object { 
        $ext = [System.IO.Path]::GetExtension($_)
        if ([string]::IsNullOrEmpty($ext)) { "NOEXT" } else { $ext.TrimStart('.') }
    } | Sort-Object Name

    # Prepare output content
    $outputContent = [System.Collections.Generic.List[string]]::new()

    foreach ($group in $groupedFiles) {
        $extension = $group.Name.ToUpper()
        $count = $group.Count

        # Add group header
        $outputContent.Add("## $extension Files ($count)")

        # Add markdown links for each file in the group
        foreach ($file in $group.Group) {
            $fileName = Split-Path $file -Leaf
            $displayName = [System.IO.Path]::GetFileNameWithoutExtension($fileName)
            
            # Handle empty display names
            if ([string]::IsNullOrEmpty($displayName)) {
                $displayName = "[Unnamed File]"
            }
            
            # Generate proper file URI
            $uri = [Uri]::new($file)
            $url = $uri.AbsoluteUri
            
            # Format as [display name](url)
            $outputContent.Add("[$displayName]($url)")
        }

        # Add tilde separators
        $separator = '~' * 120
        1..2 | ForEach-Object { $outputContent.Add($separator) }
    }

    # Remove last two separators if they exist
    if ($outputContent.Count -ge 2) {
        $outputContent.RemoveRange($outputContent.Count - 2, 2)
    }

    # Write output to file
    $outputContent | Out-File $outputFile

    # Validate file creation
    if (-not (Test-Path $outputFile)) {
        [System.Windows.Forms.MessageBox]::Show("Failed to create output file!", "Error")
        return
    }

    # Create enhanced success dialog
    $successDialog = New-Object System.Windows.Forms.Form
    $successDialog.Text = "Success"
    $successDialog.Size = New-Object System.Drawing.Size(450, 220)
    $successDialog.StartPosition = "CenterParent"
    $successDialog.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
    $successDialog.AutoSize = $true
    $successDialog.AutoSizeMode = "GrowAndShrink"
    
    # Main message components
    $labelPrefix = New-Object System.Windows.Forms.Label
    $labelPrefix.Text = "File list created with"
    $labelPrefix.Location = New-Object System.Drawing.Point(20, 20)
    $labelPrefix.AutoSize = $true
    $successDialog.Controls.Add($labelPrefix)

    $labelCount = New-Object System.Windows.Forms.Label
    $labelCount.Text = $allSelectedFiles.Count.ToString()
    $labelCount.Font = New-Object System.Drawing.Font("Segoe UI", 12, [System.Drawing.FontStyle]::Bold)
    $labelCount.ForeColor = [System.Drawing.Color]::RoyalBlue
    $labelCount.Location = New-Object System.Drawing.Point(($labelPrefix.Right + 5), 15)
    $labelCount.AutoSize = $true
    $successDialog.Controls.Add($labelCount)

    $labelSuffix = New-Object System.Windows.Forms.Label
    $labelSuffix.Text = "entries saved to:`n" + ($outputFile -replace '\\','\\')
    $labelSuffix.Location = New-Object System.Drawing.Point(20, 50)
    $labelSuffix.Size = New-Object System.Drawing.Size(400, 40)
    $successDialog.Controls.Add($labelSuffix)

    # Action buttons
    $btnOpen = New-Object System.Windows.Forms.Button
    $btnOpen.Text = "&Open File"  # Alt+O shortcut
    $btnOpen.Size = New-Object System.Drawing.Size(90, 30)
    $btnOpen.Location = New-Object System.Drawing.Point(20, 120)
    $btnOpen.Add_Click({
        Invoke-Item $outputFile
        $successDialog.Close()
    })
    $successDialog.Controls.Add($btnOpen)

    $btnClose = New-Object System.Windows.Forms.Button
    $btnClose.Text = "&Close"  # Alt+C shortcut
    $btnClose.Size = New-Object System.Drawing.Size(90, 30)
    $btnClose.Location = New-Object System.Drawing.Point(120, 120)
    $btnClose.Add_Click({ $successDialog.Close() })
    $successDialog.Controls.Add($btnClose)

    $successDialog.ShowDialog() | Out-Null
}
else {
    [System.Windows.Forms.MessageBox]::Show("No files were selected.", "Info")
}

}
else {
[System.Windows.Forms.MessageBox]::Show(“Output folder selection was canceled”, “Info”)
}

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.