The “Hey, Scripting Guys!” blog has been retired. There are many useful posts in this blog, so we keep the blog here for historical reference. However, some information might be very outdated and many of the links might not work anymore.
New PowerShell content is being posted to the PowerShell Community blog where members of the community can create posts by submitting content in the GitHub repository.
Scripting Blog [archived]
Formerly known as the "Hey, Scripting Guy!" blog
Latest posts
All good things must come to an end
Introduction of New PowerShell Community Blog and Retirement of "Hey Scripting Guy!" Blog, the passing of the Torch to a new Generation.
Testing RPC ports with PowerShell (and yes, it’s as much fun as it sounds!) New and Improved!!
Summary: Using PowerShell to identify RPC ports in use by capturing content from PowerShell We'd like to introduce you today to one of our newest bloggers! It's a froopingly awesome friend of ours, Joel Vickery, PFE. (did I mention Dr. Scripto is a big fan of books written by Douglas Adams?....oops!) Take it away Joel! Thanks Doc! So hey everybody! What do you do when you have to troubleshoot the dreaded "RPC Unavailable" error 1722, which rears its ugly head anywhere from Active Directory replication to Configuration Manager Distribution Point installations, and many other places in between? We have the ans...
Import Azure DevOps Test Plans from One Environment to Another
Summary Standardization of Azure DevOps Test Plans and Reusing Them Between Different Organizations Today we introduce Claudia Ferguson and Mike Stiers to the Scripting Blog. Claudia is a Senior Consultant with the Microsoft Active Directory Migration Services Engineer team, and Mike Stiers is a Microsoft Consultant from Toronto Canada. His focus is to help teams to use scalable infrastructure as code deployments in Azure DevOps. They put together something you will find to be very useful when you need to move DevOps test plans. There is some PowerShell here too (as it's the Scripting Blog!) but the content is...
Just go with the flow…. WorkFlow that is with Windows PowerShell
Doctor Scripto returns again with our good friend Joel Vickery, PFE who is going to touch on the use of Workflows In PowerShell. Take it away Joel! Following up on my original post Parallel Processing with jobs in PowerShell, I wanted to go into another method of running parallel processes in PowerShell, namely WorkFlows. WorkFlow is very similar to using the Start-Job/-asJob functionality but it has some distinct advantages that are fully covered in many other blog postings on TechNet. I'll mention them quickly below, but if you want deeper detail, see the When Windows PowerShell Met WorkFlow blog posting...
PowerTip: Identify Completed PowerShell Jobs with Data yet to be Received
Summary: Doctor Scripto quickly shows how to identify Completed Jobs in PowerShell which have yet to have the data Received Hey Doctor Scripto, How can I identify jobs which already completed but I haven’t done a Receive-Job on to get the data? You can do this with the Get-Job Cmdlet by targeting the -ChildJobState and -HasMoreData like the following example Get-Job -ChildJobState Completed -HasMoreData:$True PowerShell, Doctor Scripto, PowerTip, Sean Kearney
Parallel Processing with jobs in PowerShell
Joel Vickery discusses an introductory use of PowerShell jobs and working with data
PowerTip: Use Windows PowerShell to display all Environment variables
Summary: Doctor Scripto demonstrates how to use env: to show all currently set environment variables Question: Hey Doctor Scripto, I remember in DOS if I wanted to see the values of all the Environment variables; like TEMP I could just type the SET Command. How do I do this in PowerShell? Answer: You can do this in one line using the env: PowerShell drive to display all of the currently set Environment variables. dir env: PowerShell, Doctor Scripto, PowerTip, Sean Kearney
PowerTip: Identify if CredentialGuard is enabled with Windows PowerShell
Summary: Easily identify if Credential Guard is enabled using the Get-ComputerInfo Cmdlet in Windows 10 Question: Hey Doctor Scripto, how can I tell if CredentialGuard has been enabled on my Windows 10 computer? Answer: Just use the Get-ComputerInfo Cmdlet and target the DeviceGaurdSecurityServicesConfigured property. The following line will produce a Boolean $TRUE if it is enabled. 'CredentialGuard' -match ((Get-ComputerInfo).DeviceGuardSecurityServicesConfigured) PowerShell, Doctor Scripto, PowerTip, Credential Guard, Paul Greeley
Use PowerShell to Identify Unassociated Azure Resources
Summary: Save costs by Identifying Unassociated Resources left behind after deletions in Azure Q: Hey, Scripting Guy! How can I quickly identify un-associated resources in my Azure subscription? A: Hi SH! At least you know that’s a question to ask! I myself when I first began exploring this new world didn’t realize that when deleting a virtual system in Azure, not all the associated resources are deleted with it! First things first, if you’ve never done it, you’ll need to install the Azure PowerShell modules. This can be done by following the steps provided here on docs.microsoft.com Install the...
PowerTip: Using Set-ADUser with multi-valued attributes
Summary: Using the -Replace parameter with Set-ADUser to take an array to populate multi-valued attributes Question: Hey Doctor Scripto, how can I use Set-ADUser to populate multivalued attributes in Active Directory? Answer: You can use an array with the -Replace parameter to do it. Set-ADUser -Identity "TestUser" -Replace @{ProxyAddresses = @("Address1","Address2","Address3")} PowerShell, Doctor Scripto, PowerTip, Active Directory, Walid Moselhy
Copy multi-valued Active Directory attributes from one user to another with PowerShell
Summary: Using -Replace parameter with Set-ADUser to copy Active Directory multi-valued attributes Q: Hey, Doctor Scripto! We are in the middle of an Active Directory migration and need to copy the multi-valued attribute “ProxyAddresses” from old user accounts to new ones. Can you do with a few lines of code? —ND A: Hello ND, Hello everyone, your good friend Doctor Scripto is here with Walid, one of our PFEs who really likes mixing PowerShell with Active Directory. Walid, what do you think of this one? Well, Doctor Scripto, it makes a lot of sense to try and automate this type of tasks. Who like...
PowerTip: Use New-Alias to make Cmdlets easier to remember
Using New-Alias to create easier to remember shortcuts in PowerShell
Using PowerShell to View and Remove Wireless Profiles in Windows 10 – Part 4
Summary: Using Windows PowerShell to purge Wlan profiles with NetSh.exe. Last week we had a way with a Regular Expression to run one Netsh.exe command and show only the profile names as a PowerShell Array. Today we're going to finish the task and show you how to delete those Profiles. As a quick reminder here's the line in PowerShell we used to capture the list of Wireless profiles by only their names as an Array. The resulting output containing our Wireless profile names looked like this From our first posting we saw that to delete a WLAN profile in Netsh.exe we would execute this command. ...
PowerTip: Show all Installed Capabilities on Windows 10
Summary: Identify if capabilities like OpenSSH are installed in your Windows 10 Operating System Hey, Doctor Scripto. I was curious if there was a way to see if a workstation has a capability installed on it like OpenSSH. I’m trying to report on this for my environment. Absolutely! You can run the following line on a workstation to show the installed Capabilities like OpenSSH Get-WindowsCapability -Online | Where-Object { $_.State -eq 'Installed' } PowerShell, Doctor Scripto, PowerTip, Sean Kearney
Using PowerShell to View and Remove Wireless Profiles in Windows 10 – Part 3
Summary: Using Regular Expressions to cleanup string data from NetSh.exe. Let's remember the last two discussions. The first time we looked at using PowerShell to identify wireless profiles with some simple regular expressions. We followed up the next week with how to identify which approach would be the fastest. Today we're going to take that array of information and clean it up so we only have the profile names. As a quick reminder here's the line in PowerShell we used to capture the list of Wireless profiles The resulting output looked like this What we need to do now is cleanup this data so...
PowerTip: Identify Drives Encrypted with Bitlocker
Summary: Using the Get-Bitlocker Cmdlet to show the status of drives on your Windows 10 computer Hey, Doctor Scripto. Is there a nice simple way to see if drives are Bitlocker encrypted? A most excellent question! You can the Get-BitlockerVolume Cmdlet and filter on the VolumeStatus property. Here's an example of a line that will show only drives which have Bitlocker enabled. Get-BitLockerVolume | Where-Object { $_.VolumeStatus -eq 'FullyEncrypted' } PowerShell, Doctor Scripto, PowerTip, Sean Kearney
Using PowerShell to View and Remove Wireless Profiles in Windows 10 – Part 2
Summary: Using Measure-Command to determine the fastest approach to a solution. Last week we were having some fun using PowerShell as a wrapper around the NetSh.exe command's output. We were left at a decision point. Which way to go? A For loop to clean up the data, which worked fine or Regular Expressions. Although both work which was the better path to use? For me initially, when I first started in PowerShell I very often used a For loop for a few reasons. But as I progressed in my knowledge of PowerShell I've started to touch on Regular expressions as a solution when possible. A go...
PowerTip: Converting a Here-String to an Array in One Line with PowerShell
Summary: Using the split method in a more powerful fashion to split an array based upon two line terminating types Hey, Doctor Scripto. I was wondering if there was a more efficient way of converting a Here-String to an Array when there were multiple line termination options like Linefeed or Carriage Return and Linefeed? There most definitely is. You can pass multiple parameters to the split method. This example traps both! $HereStringSample=@' Banana Raspberry '@ $HereStringSample.Split(@("$([char][byte]10)", "$([char][byte]10)","$([char][byte]13)", [StringSplitOptions]::None)) PowerShe...
Using PowerShell to View and Remove Wireless Profiles in Windows 10 – Part 1
Summary: Using PowerShell and Regular Expressions as a wrapper on NetSh.exe output to identify the profiles. Hey, Doctor Scripto! I have a whole pile of old Wireless profiles that have been collecting dust. I know I can use NETSH to view and delete them, but the process is very manual. Do you know if there is an easier way to clear them up? —WF Hello WF, you asked I shall help. Doctor Scripto is in the house! I know the process you mean, I had to do this a few years ago on one of my old laptops. I had wireless profiles from my home, hotels, offices, coffee shops. It was just silly. I think there we...
PowerTip: Identify which Platform PowerShell is running on
Summary: Using $PSVersionTable to identify if you are on Windows or Unix Hey, Doctor Scripto! I'm working on my PowerShell scripts and I need to be able to identify if I'm working on Windows or Linux. How can I do this easily? No problem at all and glad to help. Just examine the $PSVersionTable property called Platform. It will contain one either 'Unix','Win32NT' on PowerShell Core. In the case of Windows PowerShell it will not exist. $PSVersionTable.Platform PowerShell, Doctor Scripto, PowerTip, Sean Kearney
Creating a Platform Independent Function in PowerShell
Summary: Creating a Function in PowerShell and the power of the $PSVersionTable to make code more portable Q: Hey, Doctor Scripto! I saw that post last week on converting Here-String into an array. I wanted to write my code to trap for PowerShell and PowerShell Core. Could you give me a helping hand? —PG A: Hello PG, Hello everyone, your good friend Doctor Scripto is here with Sean sitting across from me having lunch. Sean what do you think about this idea? Well Doctor Scripto this is actually pretty easy and it makes a LOT of sense to have a function do this to avoid re-writing the same code. ...
PowerTip: Identify if you are running on PowerShell Core
Summary: Pulling up the properties of $PSVersionTable to identify your PowerShell edition Hey, Doctor Scripto! I want to write my modules and scripts to be more portable. How can I tell if I am executing on PowerShell Core? Just use the $PSVersionTable object and examine the PSEdition value. If it returns 'Core' you are running on PowerShell core. $PSVersionTable.PSEdition PowerShell, Doctor Scripto, PowerTip, Sean Kearney
Maximizing the Power of Here-String in PowerShell for Configuration Data
Summary: Discovering some of the awesome and neat ways to leverage a Here-String in a Script or function Q: Hey, Doctor Scripto! I used to write scripts with supporting configuration files that never really changed. I was wondering if there was any way to put them INSIDE the script directly to make it self contained. —AB A: Hello AB, I was chatting with my good friend Sean on this one. Here he talks about using Here-Strings to solve this problem. Thanks Doctor Scripto, yes a Here-String can be a great way to embed the configuration or other data for that matter in a script. If you've never encou...
PowerTip: Read a JSON configuration file as a PowerShell object
Summary: Using the ConvertFrom-Json Cmdlet in PowerShell to read a JSON formatted file Hey, Doctor Scripto! I've seen a lot of JSON files in use in Azure. I'm not very good with editing JSON properly. Is there an easy way to read this and at least edit it with PowerShell? Most definitely my good friend. For the file below called "settings.json" you can convert it to a PowerShell Object for editing purposes using the following line. Once you have completed this, you can manipulate it like any other PowerShell Object. $PowerShellObject=Get-Content -Path settings.json | ConvertFrom-Json Pow...
Configuring Startup Settings in Microsoft Teams with Windows PowerShell
Summary: Using the ConvertFrom-JSON and ConvertTo-JSON Cmdlets to edit a configuration file Q: Hey, Doctor Scripto! I need to be able to change the Startup settings in Teams (like the Auto launch feature). I can change it in the Interface, but I need to be able to edit across multiple systems. Could you lend me a hand? —RL A: Hello RL, A very excellent question. For which it produced a most interesting solution when I asked Sean Kearney one of our Microsoft PFE's to look at it. Take it away Sean! Let's begin by examining the settings we are trying to change. They can be accessed under the "Setti...
PowerTip: Using PowerShell to Convert raw Text to a Comma Separated columm
Summary: Using PowerShell and a very simple Regular Expression to convert Random counts of spaces to a Comma Hey Doctor Scripto! I have some string based output from a non PowerShell application. The output is good but I need to easily parse it. Is there a way to convert that data to something consistent like "Comma Separated?" Why yes you can! This is something that is easily done with a regular expression. Using a simple example like this will identify all content with more than one blank space separating it, and replace it with a comma! $SampleText='Hello This ...
Automating Quser through PowerShell
Summary: Using PowerShell to automate Quser to identify users to Logoff systems in Windows Hey Doctor Scripto! I need to log a user off every computer they’re logged into. The problem is, I don’t know which ones. How can I discover which computers they’re logged into and then log them off? That's a most excellent question! I know just the person who can answer that. I was talking my good friend Dan Reist on this topic. Dan is a Senior Consultant on Data Platforms here at Microsoft. He actually ran into that same issue. Dan, the room is yours today, take it away! Thanks Doctor Scripto! So my ...
PowerTip: Identify if SQL Servers are configured to best practices
Summary: Using the features of the SQLServer PowerShell module to run assessments of your servers How can I easily check that my SQL Servers are all configured to meet best practices? You can use SQL Server Assessments – the latest addition to the SQLServer PowerShell module. Just Run a best practices assessment on your SQL Server as seen below Get-SqlInstance "DemoSQLServer" | Invoke-SqlAssessment PowerShell, Doctor Scripto, PowerTip, Johnathan Allen, SQL Server
Executing SQL Server Assessments from PowerShell
Summary: Using the SQLServer module cmdlets to review and monitor SQL Server instance and database configuration Q: Hey, Doctor Scripto! I have loads of SQL Servers in my area of responsibility and I know they all need certain configuration settings but I'm never confident that they are all set just right so I spend a long time every month visiting them all over RDP to give reassure myself. How can I automate this work? —AB A: Hello AB, I know the very person that can answer that question for you. It's my good friend Jonathan Allen. Let me introduce him to you. He's a SQL Server PFE from the UK. He...
PowerTip: Identify Synchronized AzureAD accounts without a License assigned
Summary: Using PowerShell to identify users who are Synchronized to AzureAD but not yet licensed Hey, Doctor Scripto! I'd love to be able to identify users Synchronized to AzureAD that haven't yet had their licenses assigned. Help a friend out? No problem at all! You can target that information with two parameters in the Get-Msoluser Cmdlet! Get-MsolUser -UnlicensedUsersOnly -Synchronized PowerShell, Doctor Scripto, PowerTip, AzureAD
Reporting on Microsoft 365 Licensing using PowerShell – Part 3
Summary: Will Martin finalizes his discussion on how to report on Microsoft 365 licensing in the cloud. Previous Posts on this article can be found here for continuity Reporting on Microsoft 365 Licensing using PowerShell – Part 1 Reporting on Microsoft 365 Licensing using PowerShell – Part 2 Dr. Scripto here! When last we saw Will Martin, he was deep in a script pulling down licensing tables and produced a lovely hash table. Let’s watch for the exciting conclusion! From last week, we placed our data in a hash table. Now, let’s swap it from a hash table to CSV format by changing our last active lin...
PowerTip: Identify the last time Users changed passwords in AzureAD
Summary: Using PowerShell to report on Users and the last time Passwords were changed Hey, Doctor Scripto! I need to report on users and when they updated their passwords In AzureAD. Could you show me how ? Most certainly, I love to provide a helping hand however I can. Using the Get-Msoluser Cmdlet just target the LastPasswordChangeTimeStamp Attribute. Here's an example of it in use. Get-MsolUser | Select-Object DisplayName, UserPrincipalName, LastPasswordChangeTimeStamp PowerShell, Doctor Scripto, PowerTip, AzureAD
Reporting on Microsoft 365 Licensing using PowerShell – Part 2
Summary: Will Martin continues his discussion on how to report on Microsoft 365 licensing in the cloud. Previous Posts on this article can be found here for continuity Reporting on Microsoft 365 Licensing using PowerShell – Part 1 Remember from last week we showed the results of what a user licensed in Microsoft 365 looked like in the web portal? So, what does this look like if we try to access it in PowerShell? Well, we have the user, and the service plan. Can we get this into a usable format? Well, let’s see what we can do – let’s try pulling this info for our last three users and see what we...
PowerTip: Identify the last time a User was Synchronized to AzureAD
Summary: Use PowerShell to identify the property in AzureAD with the Synchronization time in AzureAD Hey, Doctor Scripto. Is there a way with PowerShell to identify when a user was last synchronized with AzureAD? Absolutely! We just need to examine the LastDirSyncTime when using the Get-Msoluser cmdlet. Here’s an example below (Get-MsolUser -UserPrincipalName 'drscripto@contoso.com').LastDirSyncTime PowerShell, Doctor Scripto, PowerTip, Microsoft 365
Reporting on Microsoft 365 Licensing using PowerShell – Part 1
Summary: Will Martin discusses how to report on Microsoft 365 licensing in the cloud. Hello everyone, Doctor Scripto here today to introduce you to a good friend of mine. Will Martin is a PFE in Messaging here at Microsoft and he wanted to share a wonderful solution he found on reporting on Microsoft 365 licensing with PowerShell. Will my friend, the Blog is now in your most capable hands! Thanks for the introduction Doctor Scripto! I came across an interesting problem recently. I was asked by my large Office 365 customer if I could give them a script that would output all their user account licensing...
PowerTip: Show files with expired Digital Certificates
Summary: Targeting Expired Certificates with Get-AuthenticodeSignature Question: Hey Doctor Scripto! Is there an easy way to visually identify Digitally signed files with an Expired status on the Digital Certificate? Answer: Absolutely! We just need to filter on the “Status” property and show those without the value ‘Valid’. As an added bonus it would also identify files that are not digitally signed. Get-Childitem C:\Folder\*.* -Recurse | Get-AuthenticodeSignature | Where-Object { $_.Status -ne 'Valid' } PowerShell, Doctor Scripto, PowerTip
Reporting on Digitally Signed Files with PowerShell
Summary: Using the Get-AuthenticodeSignature cmdlet to show if a file is Digitally Signed Q: Hey, Doctor Scripto! I was curious, since many new files are Digitally signed with a certificate if there was an easy way to see the status of the Digital Signatures of many files easily? —SH A: Hello SH your good friend Doctor Scripto is here today to help you along. One of the things which changed with PowerShell in version 3.0 was a beautiful little Cmdlet called Get-AuthenticodeSignature This Cmdlets task was very simple, examine a file and show the properties of the Digital Certificate on a file. He...
Clean up Domain Controller DNS Records with Powershell
Summary: Using Windows PowerShell to remove Stale / Dead Domain Controller records. Q: Hey, Doctor Scripto! How can I quickly clean up all my dead Domain Controller’s DNS records? A: That’s a great question. The good Doctor also knows the very person to answer it best. My good friend Patrick Mercier, An Active Directory PFE who loves working with PowerShell. Take it away Patrick! Whether it’s as part of Active Directory Disaster Recovery, or because you had an old Domain Controller you needed to get rid of, cleaning up all the DNS records of a now dead DC left behind can be tedious: that is, unl...
PowerShell PowerTip: Customizing your prompt
I've been taking a break from the blog for a while due to some personal reasons, but I had a few people ask me about my PowerShell prompt recently. I like extra horizontal space, so I removed the path from the prompt and put it in the window title bar. I also just display the current time in the prompt itself. You can customize your prompt by using your profile and overriding the "Prompt" function. A coworker of mine, Tony Radkiewicz, used a similar prompt and I really liked it so I've been using it since. That's all for now, I'll try to get some...
PowerTip: Use PowerShell to pick a random name from a list
Using the Get-Random Cmdlet to select a random list of names instead of numbers
Using PowerShell to create a folder of Demo data
Creating sample files with random sizes and dates for use in a Lab
PowerShell PowerTip: searching and installing modules on the command line
PowerShell 5+ ships with the module PowerShellGet, which lets us search and install modules from cmdlets. The default nuget repository is the PowerShell Gallery, but you could add others yourself (including custom ones for internal modules). There are a lot of reasons this could help you: There are a lot of cmdlets in the module, but the ones you'll use the most will be: You can also specify the scope on install-module and put it in your user module location for ones just for you on a machine. Hope that helps, tune in more often to get short and sweet PowerTips!
Regular Expressions (REGEX): Grouping & [RegEx]
Welcome back to the RegEx crash course. Last time we talked about the basic symbols we plan to use as our foundation. This week, we will be learning a new way to leverage our patterns for data extraction and how to rip our extracted data into pieces we care about. [RegEx] The data type has some cool static members, but we're mostly going to play with the plural method if you don't know what static members are you can check this post or this help data. A lot of the time, when we work with RegEx we are using it to extract everything that matches our pattern in a large amount of data. Using like we did in t...
PowerShell PowerTip: History of commands with PSReadline
One of the really cool things PSReadline provides (module shipping on v5+) isn't as immediately obvious as the syntax highlighting. It offers a persistent history that is stored from session to session. This means if you run commands in a window, close it, and open a new one later you can still hit the up arrow and scroll through them. I use this feature quite a bit doing demos or just working on things where I want to clear out my whole scope and jump back in. If you want to opt out you can as well: Hope that helps, tune in more often to get short and sweet PowerTips!
Regular Expressions (REGEX): Basic symbols
Welcome back to the RegEx guide. Last post we talked a little bit about the basics of RegEx and its uses. I mentioned the most important thing is to understand the symbols. Today we'll ease in with some of the basics to get us going, but later we will expand on these and see some other options we have. is used to represent any single character, aside from a newline, so it will feel very similar to the windows wildcard is the escape character for RegEx, the escape character has two jobs: We can use to specify quantity in a few different ways by attaching them to characters or symbols. ...