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