Still using Credentials in your Code?

You already know that using credentials in your code is very much frowned upon. Every security expert will tell you that there are now plenty of other ways to verify access beyond user IDs and passwords, and you should always use the best verification method. But what if you need to connect to some legacy database, spreadsheet, server, or some other older piece of technology? You may not have any choice other than to use a user ID and password combination. If you solely live in a PowerShell world, you likely use stored credential objects; but what if your connection happens to be outside the realm of PowerShell?

Why is putting credentials in your code a problem?

If you hard-code user IDs and passwords in your code, you practically advertise them to all users on that computer. With Script Block Logging enabled (as it should be), your users just have to look at the code in your Windows Event log to see the user ID and password for that network database. This is very much like leaving your valuables visible in your car at the mall—you should at least put them in the trunk to prevent crimes of opportunity.

I am aware that many computer security folks now scream, “There is no security in obscurity”, while commencing with some agitated hand waving. Nonetheless, you put your shopping bags in the trunk and you lock your car at the mall. Sure, it does not deter the professional car thief or the repo man with a flatbed truck; but it is still a common-sense practice and is recommended repeatedly by every local police department.

So from now on, add your credentials to a packaged script—where they are saved encrypted—and load them into a variable only at runtime.

If you now ask, “How are they encrypted?” and “With what algorithm to which standards?” you are missing the point. This mechanism does not provide any real security from a person determined to get these credentials. Once you run the packaged app and attach with a debugger, you can always find a way to see the credentials. Adding credentials to a packaged script does not get around that; having some stranger sit at your computer and debug your application is an entirely different problem. So this new mechanism we are introducing prevents your credentials from being advertised in Windows logs for everyone to see. Your code changes from this:

Connect-Database -User “DarthVader” -Password “LukeSkywalker1977”

To this:

Connect-Database -User $SAPIENHost.GetUserID(0) -Password $SAPIENHost.GetPasswordString(0)

You can also use $SAPIENHost.GetPassword(index) to obtain a SecureString object containing your password.

The index used in these calls is based on the order in which you specified credentials in the Script Packager tool. Please keep in mind that indexing starts at 0, not 1.

You should definitely check that $SAPIENHost is not null before making these calls. Running a script using these methods in a default PowerShell console will only produce errors.


This mechanism is only available in packaged scripts, and when running your script from PrimalScript or PowerShell Studio—you will need PrimalScript 8.0.159 or PowerShell Studio 5.8.199 at a minimum. The packager engines supporting this are for Windows PowerShell 5.1 and PowerShell 7 versions 7.0.8, 7.1.5, and 7.2.1 or later.

As always, if you have any feedback or suggestions, let us know in the comments or in our support forums.