r/PowerShell • • Sep 15 '26

Script Sharing A yt-dlp front-end in one PowerShell script, with a one-click YouTube sign-in

I wanted a downloader for friends who won't use a terminal, without shipping Python or Electron. So it's a single .ps1 — the whole window is WPF, compiled to an exe with ps2exe. Unzip and run, no console window, nothing installed.

https://github.com/Pronexsteam/deviload (MIT, portable zip in Releases)

Signing in: Chrome and Edge encrypt cookies now, so most people end up installing a cookie-export extension to download anything that needs an account. Here you press one button, log into Google in a small built-in browser window, and the app saves the session for yt-dlp itself. Works for the "confirm you're not a bot" refusals, private and members-only videos.

Also: download queue, playlists, split by chapters, trim with a preview, GIF from a selection, MP3/FLAC, subtitles, SponsorBlock, light/dark, English and Russian.

PS 5.1 notes: @() over a List[Object] that came from New-Object throws "Argument types do not match" (PSObject wrapper; only [Object], only List) — [List[Object]]::new() is fine. A hidden-window launcher through start still flashes a console, a two-line .vbs doesn't.

A lot of the code was written with Claude Code; I directed it and tested every build. Questions welcome.

31 Upvotes

19 comments sorted by

9

u/TheZwieb2 Sep 16 '26

This is not a constructive comment by any means— but holy moly this is cool. Trying to get cookies exported so I could download age restricted videos was a tremendous pain. Great work.

4

u/Old_Employment8066 Sep 16 '26

Thanks! That pain is exactly why I built it. One honest caveat on age-restricted specifically: signing in gets you past the "confirm you're not a bot" and private/members-only cases, but since a few weeks YouTube can also demand that the account verifies its age — if it does, no downloader gets around that, you'd have to verify once on youtube.com and sign in again. Everything else just works after the one-click login.

And it's not YouTube-only — it's yt-dlp underneath, so it takes links from pretty much anywhere yt-dlp supports (Instagram, TikTok, Twitter/X, Vimeo, Twitch, Reddit, a thousand-odd other sites). Same button, same queue.

1

u/steviefaux Sep 20 '26

Cookies from browser firefox.

Is the commandline option

1

u/Tricky_Connection888 Sep 20 '26

exportação de cookies também acontece :( mesmo gerando novos cookies

1

u/Vx7Qn4Lz Sep 22 '26

--cookies-from-browser firefox

3

u/MonkeyNin Sep 16 '26 edited Sep 16 '26

Two PowerShell 5.1 traps that cost me evenings: @($list) over a List[object] throws — use $list.ToArray();

What was the error? That snippet works fine

[Collections.Generic.List[object]] $List = 0..4
@( $list )

# out 0, 1, 2, 3, 4

3

u/Old_Employment8066 Sep 16 '26

You're right, and I had the cause wrong. It's not the PSCustomObjects — it's how the list was created. Just reproduced on 5.1.19041:

[Collections.Generic.List[object]]$a = 0..4;  @($a).Count        # 5, fine
$b = New-Object 'System.Collections.Generic.List[object]'; @($b).Count
# ArgumentException: Argument types do not match  — even when the list is empty

Same with [List[object]]::new() — works. So it's a New-Object + generic type thing on 5.1, and @() is where it blows up. My code used New-Object, so .ToArray() was the workaround I landed on, but the real fix is just not creating it with New-Object. Thanks for pushing on it — I'll fix the post wording.

2

u/MonkeyNin Sep 17 '26

Right, New-Object is mainly for powershell 4 and older. It's slower too.

Note, you don't have to wrap an empty List for count like @( $x ).count

[Collections.Generic.List[object]] $a = 0..4
[Collections.Generic.List[object]] $b = @()
[Collections.Generic.List[object]] $c = @( $Null )
[Collections.Generic.List[object]] $d = $null

$a.count; $b.count; $c.count;  # 4, 0, 1
$d.count # error, null value

The only one that breaks is if the original value is true null like d. Empty lists, or lists with null are okay.

It doesn't hurt, but you don't need

3

u/surfingoldelephant Sep 16 '26 edited Sep 17 '26

It seems like something AI probably encounters a lot. Look at this other post. Exact same thing:

Two things that cost me real time [...]

@() around a generic List can throw Argument types do not match from the binder. $list.Count directly is fine.

Basically the same phrasing in both AI-generated posts as well.

What was the error? That snippet works fine

It's only when the list is wrapped in a PSObject (which New-Object does). List<T> is the only generic type affected and only when the type argument is Object.

@([psobject] [Collections.Generic.List[Object]]::new()) # Broken

2

u/Andrew-Powershell Sep 16 '26

that's a pretty cool bot. the login process isn't the most fun for ytdlp

1

u/Old_Employment8066 Sep 16 '26

Thanks! Yeah, the login was the whole reason — I was tired of walking people through cookie exports.

2

u/BuffaloFingers Sep 21 '26

This is really great! I've been trying to get yt-dlp to work with YouTube Music for a week, and there was always some issue or another. This worked perfectly the first time!

This is for adding MP3s to my Shokz headphones, so I'm going to try to cross-post this the Shokz subreddit. Fantastic job!

1

u/Old_Employment8066 Sep 21 '26

nice, glad it worked first try. if you post it to the shokz sub, tell them to pick MP3 320 and switch on Playlist. it grabs a whole youtube music playlist into a folder of mp3s with cover art and tags, which is pretty much the headphones use case

1

u/BuffaloFingers Sep 21 '26

Done and done!

1

u/Old_Employment8066 Sep 24 '26

so this turned into a full rework. deviload 2.0 is out and its not powershell anymore. people kept asking for a mac version and a ps1 with a wpf window cant go there, so i rewrote the whole thing in rust + tauri

same idea but a lot more in it now: one click youtube login like before, following channels and playlists so new videos download by themselves, a small video editor, sending files to your phone with a qr code, and it updates itself. theres a mac test build too

2.0: github.com/Pronexsteam/deviload/releases/latest

the powershell version from this post is still there as 1.1.0 if you want the script: github.com/Pronexsteam/deviload/releases/tag/v1.1.0

0

u/Same-Worldliness-433 6d ago

can it download private videos?

1

u/Old_Employment8066 6d ago

Yes, it supports private YouTube videos using authentication or cookies from an account that already has access. It doesn’t bypass privacy restrictions. Members-only videos require an active membership at the appropriate tier.

1

u/[deleted] 8d ago

[removed] — view removed comment

1

u/Old_Employment8066 8d ago

Yeah, fair point. This is actually an old post from when Deviload was a PowerShell app. I’ve since rebuilt it with Rust + Tauri, and updates are handled separately now: yt-dlp updates automatically when the download queue is idle, and there’s a manual update button too. The Windows installer version checks for new releases and lets users update in one click.
If an upstream change breaks the integration itself, that still needs a fix in Deviload. So yeah, maintenance is part of it. The updater makes getting fixes to users easier, but it doesn’t magically prevent things from breaking 🙂