Инструменты power shell pro

PowerShell switch statements are one of the easiest ways to compare an expression to multiple conditions. It’s kind of like nesting multiple if statements, but much prettier to look at and easier to understand. In this comprehensive guide, we go over the details and look at several examples you can use to spruce up your PowerShell scripts.

Throughout this guide, I’m using PowerShell version 7.4.3 (formerly called PowerShell Core). However, all of the examples we go over should also work for Windows PowerShell version 5.1. If something doesn’t run as expected, try running it in the latest version of PowerShell.

What is a switch statement?

A switch statement in PowerShell is a simplified way to compare a value against multiple possible results, similar to multiple nested if statements. If a condition evaluates to true, any associated action executes.

How to use a switch statement in PowerShell

Here’s what the basic syntax of a switch statement looks like.

Now, let’s look at an actual example of a PowerShell switch statement.

PowerShell switch statement example number one.

Switch vs. if statements

PowerShell switch and if statements are similar in many ways and are often interchangeable with a few formatting differences and parameters. Even performance results aren’t drastically different (though specific situations and more advanced conditions could return greater performance differences).

The most common factor when choosing between a switch and an if statement with PowerShell comes down to readability. In most cases, if you are evaluating more than two or three conditions, switch statements become much easier to read.

This script identifies the current day of the week and returns a menu item depending on the result. You may even recognize this script from my PowerShell if statements article. It’s comprised of several if, elseif, and else statements, which can appear repetitive and convoluted. By comparison, here’s a script that returns the same results but uses a switch statement instead of an if statement.

The switch statement is much more scannable and easier to read. Even though the if statement uses fewer lines, it has to repeat the command and comparison operator throughout the example, making it more difficult to read.

Using the default clause with switch statements

The default clause is a built-in keyword that determines what to do if no match is found. Instead of returning nothing, the default clause is given an action to perform just like any other value. Here’s an example of using the default clause.

Since the expression “teal” doesn’t match any of the other values, it executes the default action.

PowerShell switch statement example number two.

PowerShell switch parameters

The PowerShell switch statement includes several parameters to help define expressions and input sources. Here are a list of the available switch parameters directly from Microsoft’s help documentation.

Wildcard: Indicates that the condition is a wildcard string. If the match clause is not a string, the parameter is ignored. The comparison is case-insensitive.

Exact: Indicates that the match clause, if it is a string, must match exactly. If the match clause is not a string, this parameter is ignored. The comparison is case-insensitive.

CaseSensitive: Performs a case-sensitive match. If the match clause is not a string, this parameter is ignored.

File: Takes input from a file rather than a <test-expression>. If multiple File parameters are included, only the last one is used. Each line of the file is read and evaluated by the switch statement. The comparison is case-insensitive.

PowerShell power user?

Check out The PowerShell Podcast: a weekly exploration of tips and tricks to help you step up your PowerShell game.

How to use multiple expressions in a switch statement

Switch statements can evaluate multiple expressions in the same statement. This can be in the form of an array, multiple variables, integers, strings, etc.

When submitting multiple expressions, separate them with a comma. Multiple expressions are evaluated in the order they are written.

PowerShell switch statement example number three.

Here we evaluate the letters “a,” “b,” and “d.” Both “a” and “b” return true, but “d” doesn’t match any of the conditions.

:/>  Как убрать программы из автозапуска в Windows 10 »

PowerShell switch break vs. continue

PowerShell switch statement example number four.

If you don’t want an expression to match more than once, you can either use the continue or break statement. A continue statement stops evaluating the current expression once a match is found; however, it proceeds to evaluate the next expression if there is one available.

In this example, we use the continue statement to limit each expression to match only one condition. Once the second condition evaluates and matches 2, the switch statement moves onto the next value in the variable, eliminating duplicate matches. Here is the result.

PowerShell switch statement example number five.

If you want to stop the entire switch once a specific condition is met, use the break statement. Here’s what happens if I replace the continue statement with a break statement in the same example.

PowerShell switch statement example number six.

The break statement stops the switch from evaluating anything after the first condition returns true.

Switch statement examples

What’s that? You’re still here and you want more PowerShell switch statement examples? Well, as any good rock star concedes to their adoring fans chanting encore, I guess I could muster up a couple more examples to keep my fans happy.

Using switch statements to identify running processes

PowerShell switch statement example number seven.

Counting files by file type with the PowerShell switch statement

In this example, the PowerShell script returns the number of specific file types found in a given directory.

Here are the results when I run this script in my test environment.

PowerShell switch statement example number eight.

You can easily add more document types to this script to meet your needs. Also, consider adding a default condition for files with no matching file type listed.

Get-Help about_switch info

Hopefully this guide helps you add to your PowerShell repertoire. If you’re interested in more PowerShell basics, definitely check out our guide on PowerShell loops. And if you’re still stuck using the command line, it’s not too late. We have tons of articles that teach you the PowerShell equivalents of your favorite cmd commands, like our PowerShell equivalent of dsquery article.

Lastly, if you need help running scripts against your managed devices, check out PDQ Connect or PDQ Deploy & Inventory. Connect is an agent-based solution that makes local and remote device management easy. Deploy & Inventory specialize in on-prem device management and don’t require an agent installation.

Brock Bingham candid headshot

Born in the ’80s and raised by his NES, Brock quickly fell in love with everything tech. With over 15 years of IT experience, Brock now enjoys the life of luxury as a renowned tech blogger and receiver of many Dundie Awards. In his free time, Brock enjoys adventuring with his wife, kids, and dogs, while dreaming of retirement.

Refactoring

Refactoring commands for VS Code.

Refactorings allow you to change or generate code based on the code you have. You will find a list of refactors below. You can invoke a refactor by invoke the Refactor command or by pressing the key binding Ctrl+Alt+R .

Only valid refactors will be returned in the drop down menu.

Convert to $_

This refactoring converts a $PSItem variable to the $_ variable.

Convert to $PSItem

Converts a reference to the $_ variable to $PSItem.

Convert to Multiline Command

Converts a command invocation into a multi-line command. Each parameter and argument is broken up with backticks.

Convert to Splat

Converts a command invocation into a splatting expression and creates a hashtable named $Parameters and then passes that hashtable as a splatting expression to the command. Positional arguments are not added to the hashtable.

Export Module Member

Exports the selected variable or function from a module using Export-ModuleMember.

You can use the Extract Selection to File refactor to create a new file based on the selection in the current active editor.

Generate Function from Usage

You can generate a function based on a command example. This refactoring will analyze the parameters, arguments and whether the command is used in a pipeline. If used in a pipeline, this refactoring will generate an advanced function.

:/>  Восстановите и загрузите dxdiag.exe сейчас - WinPCWare

Generate Proxy Function

Proxy functions allow you to extend existing functions with new parameters and functionality. You can select a command that you use within your script and select the Generate Proxy Function refactoring to have it generate the proxy function code for you.

Introduce Using Namespace

The introduce using namespace refactoring adds a using namespace statement to the top of a script and replaces the selected type expression with the namespace removed.

You can reorder parameters by using the Ctrl+PageUp and Ctrl+PageDown key bindings. Ensure that your cursor is on top of a parameter for a command. Press one of the key bindings. To move a parameter to the right, use Page Up. To move a parameter to the left, use Page Down.

The split pipe refactoring will split a pipe into multiple lines. Each element in the pipe is stored in a variable and passed to the next item in the pipe. This can be useful for debugging long or complex pipeline operations.

How can I pass values to my functions in the same way the PowerShell cmdlet Write-Output can be passed multiple values and process them as expected?

'one', 'two' | Write-Output
one
two

I thought this was a way to do that, but it isn’t:

Function ProcessNames ([Parameter(ValueFromPipeline=$true)][string[]]$Names) { Foreach ( $name in $Names ) { # do something }
}
'bob', 'alice' | ProcessNames

In the above example, only the last element in the list gets processed – in this case ‘alice’.

What am I doing wrong?

asked Aug 23, 2023 at 15:49

David's user avatar

Function ProcessNames ([Parameter(ValueFromPipeline=$true)][string[]]$Names) { PROCESS{ Foreach ( $name in $Names ) { $name } }
}
'bob', 'alice' | ProcessNames

answered Aug 23, 2023 at 16:01

TheMadTechnician's user avatar

3 gold badges45 silver badges59 bronze badges

To add to TheMadTechnician’s helpful answer:

    • Only a param(...) block allows you to use the [CmdletBinding()] attribute, which modifies the behavior of advanced functions – see this answer.
  • If your intent is to support processing multiple input objects via the pipeline only, you needn’t declare your pipeline-binding parameter as an array.


Supporting multiple input objects via the pipeline only simplifies – and speeds up – things:

function ProcessNames { param( [Parameter(ValueFromPipeline)] [string] $Name # Defined as a *single* string ) process { # Do something with $Name $Name + '!' # sample operation }
}

filter ProcessNames { # Do something with $_ $_ + '!' # sample operation
}

answered Oct 11, 2023 at 22:42

mklement0's user avatar

68 gold badges673 silver badges862 bronze badges

Today’s increased demand for efficiency in IT necessitates knowledge of how to speed up workflow using powerful tools such as PowerShell and Intune.

It is the scripting capability provided by PowerShell that enables the automation of complex tasks, which are performed repeatedly, while Intune, part of Microsoft’s Endpoint Manager, allows devices and applications in an organization to be managed. This makes them achieve improved efficiencies and compliance in Windows application management.

Recap of Part 1: Retrieving Win32 Apps

In our first part titled “PowerShell & Intune automate your work: Part 1 – Retrieve Win32 Apps,” we covered several foundational skills that are essential when interacting with Azure and Microsoft Graph API through PowerShell. We went over some fundamental aspects of the AZ Module, negotiating authorization processes with Azure as well as what Microsoft Graph can do.

Retrieve Win32 App Assignments in Intune using PowerShell

Moving on from our initial exploration, this article delves into retrieving Win32 App Assignments.

Our script kicks off by establishing a connection to Microsoft Graph using specific scopes necessary for accessing detailed app data. These scopes include:

  • “User.Read.All”
  • “Group.ReadWrite.All”
  • “DeviceManagementApps.Read.All”
  • “DeviceManagementApps.ReadWrite.All”
  • “GroupMember.Read.All”
  • “Directory.Read.All”
  • “Directory.ReadWrite.All”
  • “Group.Read.All”

During the first run and the initial login in your tenant, you will be asked to provide consent to the above scopes:

Permission requested by Microsoft

Alternatively, you can also check the permissions and consent to them when you use the Graph Explorer. Just go to the Modify Permissions tab and everything needed for the operation will be displayed there.

Microsoft Graph Explorer view

Upon connection, the script fetches all Win32 applications using a targeted Graph API request.

:/>  Imap для учетных записей go daddys microsoft 365 с использованием power shell

For each application retrieved, it then queries for associated assignments:

Where-Object { ($PSItem.target.'@odata.type' -like "*groupAssignmentTarget") -or ($PSItem.intent -like $Intent) }

These are the configurations that dictate how apps are distributed to various groups within the organization.

The script meticulously parses through these assignments to determine details such as the group’s inclusion or exclusion status and the specifics of deployment settings like notifications and restart behavior.

Each piece of assignment data is processed and stored in a custom PowerShell object, providing a structured and actionable overview of app distribution across the organization.

Error handling is built into the script to manage and report any issues encountered during the data retrieval process, ensuring robust and reliable execution.

$PSObject = [PSCustomObject]@{	Type = $Win32AppAssignment.target.'@odata.type'	AppName = $Win32MobileApp.displayName	GroupID = $Win32AppAssignment.target.groupId	GroupName = $AzureADGroupResponse.displayName	Intent = $Win32AppAssignment.intent	GroupMode = $GroupMode	Notifications = $Win32AppAssignment.settings.notifications	RestartSettings = $Win32AppAssignment.settings.restartSettings	InstallTimeSettings = $Win32AppAssignment.settings.installTimeSettings	}	$Win32AppAssignmentList.Add($PSObject) | Out-Null

Here is the full script for these operations:

Connect-MgGraph -Scopes "User.Read.All", "Group.ReadWrite.All", "DeviceManagementApps.Read.All", "DeviceManagementApps.ReadWrite.All", "GroupMember.Read.All", "Directory.Read.All", "Directory.ReadWrite.All", "Group.Read.All"
$Win32AppList = New-Object -TypeName "System.Collections.Generic.List[Object]" $Win32AppAssignmentList = New-Object -TypeName "System.Collections.Generic.List[Object]"
$Win32MobileApps = Invoke-MgGraphRequest -Method GET "https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps?`$filter=isof('microsoft.graph.win32LobApp')" if ($Win32MobileApps -ne "") {	$Win32MobileApps = $Win32MobileApps.value	if ($Win32MobileApps -ne $null) {	foreach ($Win32MobileApp in $Win32MobileApps) {	#$Win32MobileApp.id | Out-String | Write-Host	$Win32MobileApps2 = Invoke-MgGraphRequest -Method GET "https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps/$($Win32MobileApp.id)/assignments"	#$Win32MobileApps2.value | Out-String | Write-Host	# $Win32AppList.Add($Win32MobileApp)	$Win32AppAssignmentMatches = $Win32MobileApps2.value | Where-Object { ($PSItem.target.'@odata.type' -like "*groupAssignmentTarget") -or ($PSItem.intent -like $Intent) }	#$Win32AppAssignmentMatches.id | out-string | write-host	foreach ($Win32AppAssignment in $Win32AppAssignmentMatches) {	try {	# Retrieve group name from given group id	$Win32AppAssignmentValue = $Win32AppAssignment.target.groupId	$AzureADGroupResponse = Invoke-MgGraphRequest -Method GET "https://graph.microsoft.com/v1.0/groups/$Win32AppAssignmentValue"	# Determine if assignment is either Include or Exclude for GroupMode property output	switch ($Win32AppAssignment.target.'@odata.type') {	"#microsoft.graph.groupAssignmentTarget" {	$GroupMode = "Include"	}	"#microsoft.graph.exclusionGroupAssignmentTarget" {	$GroupMode = "Exclude"	}	}	# Create a custom object for return value	$PSObject = [PSCustomObject]@{	Type = $Win32AppAssignment.target.'@odata.type'	AppName = $Win32MobileApp.displayName	GroupID = $Win32AppAssignment.target.groupId	GroupName = $AzureADGroupResponse.displayName	Intent = $Win32AppAssignment.intent	GroupMode = $GroupMode	Notifications = $Win32AppAssignment.settings.notifications	RestartSettings = $Win32AppAssignment.settings.restartSettings	InstallTimeSettings = $Win32AppAssignment.settings.installTimeSettings	}	$Win32AppAssignmentList.Add($PSObject) | Out-Null	# $PSObject | out-string | write-host	}	catch [System.Exception] {	Write-Warning -Message "An error occurred while resolving groupId for assignment with ID: $($Win32AppAssignment.id). Error message: $($_.Exception.Message)"	}	return $Win32AppAssignmentList	}	}	}}

Retrieve Win32 App Assignments for a Particular Application

If you only want to find the assignments for a specific application based on the DisplayName, you can easily adapt the script.

All you need to do is check if the DisplayName matches your target application.

if($Win32MobileApp.displayName -like "*vlc*"){
IInvoke-MgGraphRequest -apps

Here’s the full modified code for searching the assignments of a particular app in Intune with PowerShell:

Connect-MgGraph -Scopes "User.Read.All", "Group.ReadWrite.All", "DeviceManagementApps.Read.All", "DeviceManagementApps.ReadWrite.All", "GroupMember.Read.All", "Directory.Read.All", "Directory.ReadWrite.All", "Group.Read.All"
$Win32AppList = New-Object -TypeName "System.Collections.Generic.List[Object]" $Win32AppAssignmentList = New-Object -TypeName "System.Collections.Generic.List[Object]"
$Win32MobileApps = Invoke-MgGraphRequest -Method GET "https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps?`$filter=isof('microsoft.graph.win32LobApp')" if ($Win32MobileApps -ne "") {	$Win32MobileApps = $Win32MobileApps.value	if ($Win32MobileApps -ne $null) {	foreach ($Win32MobileApp in $Win32MobileApps) {	if($Win32MobileApp.displayName -like "*vlc*"){	# $Win32MobileApp.id | Out-String | Write-Host	$Win32MobileApps2 = Invoke-MgGraphRequest -Method GET "https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps/$($Win32MobileApp.id)/assignments"	$Win32AppAssignmentMatches = $Win32MobileApps2.value | Where-Object { ($PSItem.target.'@odata.type' -like "*groupAssignmentTarget") -or ($PSItem.intent -like $Intent) }	foreach ($Win32AppAssignment in $Win32AppAssignmentMatches) {	try {	$Win32AppAssignmentValue = $Win32AppAssignment.target.groupId	$AzureADGroupResponse = Invoke-MgGraphRequest -Method GET "https://graph.microsoft.com/v1.0/groups/$Win32AppAssignmentValue"	switch ($Win32AppAssignment.target.'@odata.type') {	"#microsoft.graph.groupAssignmentTarget" {	$GroupMode = "Include"	}	"#microsoft.graph.exclusionGroupAssignmentTarget" {	$GroupMode = "Exclude"	}	}	# Create a custom object for return value	$PSObject = [PSCustomObject]@{	Type = $Win32AppAssignment.target.'@odata.type'	AppName = $Win32MobileApp.displayName	GroupID = $Win32AppAssignment.target.groupId	GroupName = $AzureADGroupResponse.displayName	Intent = $Win32AppAssignment.intent	GroupMode = $GroupMode	Notifications = $Win32AppAssignment.settings.notifications	RestartSettings = $Win32AppAssignment.settings.restartSettings	InstallTimeSettings = $Win32AppAssignment.settings.installTimeSettings	}	$Win32AppAssignmentList.Add($PSObject) | Out-Null	}	catch [System.Exception] {	Write-Warning -Message "An error occurred while resolving groupId for assignment with ID: $($Win32AppAssignment.id). Error message: $($_.Exception.Message)"	}	return $Win32AppAssignmentList	}	}	}	}}

Conclusion

In addition, it saves time and improves accuracy thus reducing human errors during this process.

We are currently building on our PowerShell & Intune knowledgebase as we consider how IT operations could be improved and how security automation could be achieved.

See author's page

Alex Marin

Application Packaging and SCCM Deployments specialist, solutions finder, Technical Writer at Advanced Installer.