What’s RFF? →

VBScript to PowerShell

Drop a .vbs file and get PowerShell back, plus a count of what still needs a human. Lines it can’t convert cleanly come back as # TODO with your original underneath.

Converted in your browser. Nothing is uploaded.

What breaks if you convert it by hand

VBScript and PowerShell look close enough that a text swap compiles. Then it runs, finishes without an error, and gives you a different answer. These are the ones that get people:

The output carries one small helper function per behaviour it has to keep, and only the ones your script actually uses. You get a single self-contained .ps1 with no module to install.

What it flags instead of converting

On Error Resume Next. VBScript carries on at the next statement and PowerShell has nothing that does that. $ErrorActionPreference = "SilentlyContinue" only quiets non-terminating errors and won’t resume anything, so on a script PDQ or your RMM grades by exit code, a swallowed error lands in the console as a successful deployment.

ByRef parameters that get written to. Where the write is visible in the script you get the parameter name and the line number, so you can decide whether it needs a [ref] or a return value.

Everything else it can’t do cleanly comes back as a # TODO with your original line underneath. Thirty TODOs means thirty decisions, and it’s better to see that number before you start than three days in.

Open source

It's MIT-licensed at github.com/deadarcher/vbs-to-powershell. The converter on this page is byte-identical to the one in the repo, and our CI fails the build if they ever drift. The engine is one dependency-free file, so you can batch-convert a folder of scripts from Node, or self-host the page with one line of Docker:

docker run --rm -p 8080:80 ghcr.io/deadarcher/vbs-to-powershell:latest

Converted something wrong? Open an issue with the smallest VBScript that shows it and what you expected.

Questions

Is my script uploaded anywhere?

No. It's JavaScript running in your browser. No upload, no storage, no account. Watch the network tab if you want, or kill your network first and drop the file anyway. It still works.

Can I just run the output?

Not without reading it first. Work through the # TODOs and test it somewhere you don't mind breaking. You're getting a head start on the port, not a finished script.

Why not just swap & for + and be done?

In VBScript & always concatenates, so "1" & 2 gives you the string "12". In PowerShell "1" + 2 gives you 3. Nothing errors. You just get a number where you used to get a string, and you find out about it somewhere else in the script. The output uses a helper that keeps the VBScript behaviour.

What happens to On Error Resume Next?

It gets flagged for you to deal with. VBScript carries on at the next statement, and PowerShell has nothing that does that. $ErrorActionPreference = "SilentlyContinue" only quiets non-terminating errors, it won’t resume anything. On a script PDQ or your RMM is grading by exit code, a swallowed error shows up in the console as a successful deployment. What the tool says about it depends on how you told it the script gets deployed.

Why does it ask how the script is deployed?

Same script, different stakes. A logon script can't block, so a MsgBox buried in one is a real problem. An RMM push is judged entirely on its exit code. A scheduled task runs as SYSTEM with no desktop, so anything waiting on input sits there until the task times out. That changes the verdict and what it tells you about error handling.

How accurate is it?

Across 610 real sysadmin scripts pulled off GitHub: 98% of lines convert, and 94% of whole files come out as PowerShell that parses clean. There's also a 168-case suite that runs the VBScript and the generated PowerShell against the same inputs and compares the values, which is what catches output that runs fine and returns the wrong thing. It passes. None of that tells you your script is OK, so test it.

Does it handle Classes, Functions and ByRef?

Classes and Functions yes, including the implicit return through the function name. ByRef gets flagged, not converted. It's the default in VBScript and it isn't in PowerShell, so a Sub that writes to its argument quietly stops affecting the caller. Where that write is visible, you get the parameter name and the line number.

What about encoded .vbe files?

It reads UTF-16 and BOMs, which covers most of the .vbs files you'll actually run into. Encoded .vbe uses Microsoft's script encoder, and that doesn't get decoded here.