/
githubmirror
/
PowerShell
Обзор
Документация
Войти
/
githubmirror
/
PowerShell
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1
425 строк
20 KB
Patrick Meinecke
Suppress false positive PSScriptAnalyzer warnings in tests and build scripts (#25864)
19 авг 2025, 09:51
Не верифицирован
19 авг 2025, 09:51
c5f2446
Код
Авторство
О чём код?
# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')] param() Import-Module (Join-Path -Path $PSScriptRoot '..\Microsoft.PowerShell.Security\certificateCommon.psm1') Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows" { BeforeAll { $originalDefaultParameterValues = $PSDefaultParameterValues.Clone() if ( -not $IsWindows ) { $PSDefaultParameterValues["it:skip"] = $true } if ($IsWindows) { $userName = "testuserservices" $testPass = [Net.NetworkCredential]::new("", (New-ComplexPassword)).SecurePassword $creds = [pscredential]::new(".\$userName", $testPass) $SecurityDescriptorSddl = 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;SU)' $WrongSecurityDescriptorSddl = 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BB)(A;;CCLCSWLOCRRC;;;SU)' net user $userName $creds.GetNetworkCredential().Password /add > $null $testservicename1 = "testservice1" $testservicename2 = "testservice2" $svcbinaryname = "TestService" $svccmd = Get-Command $svcbinaryname $svccmd | Should -Not -BeNullOrEmpty $svcfullpath = $svccmd.Path $testservice1 = New-Service -BinaryPathName $svcfullpath -Name $testservicename1 $testservice1 | Should -Not -BeNullOrEmpty $testservice2 = New-Service -BinaryPathName $svcfullpath -Name $testservicename2 -DependsOn $testservicename1 $testservice2 | Should -Not -BeNullOrEmpty } Function CheckSecurityDescriptorSddl { Param( [Parameter(Mandatory)] $SecurityDescriptorSddl, [Parameter(Mandatory)] $ServiceName ) $Counter = 0 $ExpectedSDDL = ConvertFrom-SddlString -Sddl $SecurityDescriptorSddl # Selecting the first item in the output array as below command gives plain text output from the native sc.exe. $UpdatedSDDL = ConvertFrom-SddlString -Sddl (sc sdshow $ServiceName)[1] $UpdatedSDDL.Owner | Should -Be $ExpectedSDDL.Owner $UpdatedSDDL.Group | Should -Be $ExpectedSDDL.Group $UpdatedSDDL.DiscretionaryAcl.Count | Should -Be $ExpectedSDDL.DiscretionaryAcl.Count $UpdatedSDDL.DiscretionaryAcl | ForEach-Object -Process { $_ | Should -Be $ExpectedSDDL.DiscretionaryAcl[$Counter] $Counter++ } } } AfterAll { $global:PSDefaultParameterValues = $originalDefaultParameterValues if ($IsWindows) { net user $userName /delete > $null Stop-Service $testservicename2 Stop-Service $testservicename1 Remove-Service $testservicename2 Remove-Service $testservicename1 } } It "SetServiceCommand can be used as API for '<parameter>' with '<value>'" -TestCases @( @{parameter = "Name" ; value = "bar"}, @{parameter = "DisplayName" ; value = "hello"}, @{parameter = "Description" ; value = "hello world"}, @{parameter = "StartupType" ; value = "Automatic"}, @{parameter = "StartupType" ; value = "Disabled"}, @{parameter = "StartupType" ; value = "Manual"}, @{parameter = "Status" ; value = "Running"}, @{parameter = "Status" ; value = "Stopped"}, @{parameter = "Status" ; value = "Paused"}, @{parameter = "InputObject" ; script = {Get-Service | Select-Object -First 1}}, # cmdlet inherits this property, but it's not exposed as parameter so it should be $null @{parameter = "Include" ; value = "foo", "bar" ; expectedNull = $true}, # cmdlet inherits this property, but it's not exposed as parameter so it should be $null @{parameter = "Exclude" ; value = "foo", "bar" ; expectedNull = $true} ) { param($parameter, $value, $script, $expectedNull) $setServiceCommand = [Microsoft.PowerShell.Commands.SetServiceCommand]::new() if ($script -ne $null) { $value = & $script } $setServiceCommand.$parameter = $value if ($expectedNull -eq $true) { $setServiceCommand.$parameter | Should -BeNullOrEmpty } else { $setServiceCommand.$parameter | Should -Be $value } } It "Set-Service parameter validation for invalid values: <script>" -TestCases @( @{ script = {Set-Service foo -StartupType bar -ErrorAction Stop}; errorid = "CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.SetServiceCommand" }, @{ script = {Set-Service -Name $testservicename1 -SecurityDescriptorSddl $WrongSecurityDescriptorSddl }; errorid = "System.ArgumentException,Microsoft.PowerShell.Commands.SetServiceCommand" } ) { param($script, $errorid) { & $script } | Should -Throw -ErrorId $errorid } It "Sets securitydescriptor of service using Set-Service " { Set-Service -Name $TestServiceName1 -SecurityDescriptorSddl $SecurityDescriptorSddl CheckSecurityDescriptorSddl -SecurityDescriptor $SecurityDescriptorSddl -ServiceName $TestServiceName1 } It "Set-Service can change '<parameter>' to '<value>'" -TestCases @( @{parameter = "Description"; value = "hello"}, @{parameter = "DisplayName"; value = "test spooler"}, @{parameter = "StartupType"; value = "Disabled"}, @{parameter = "Status" ; value = "running" ; expected = "OK"} ) { param($parameter, $value, $expected) $currentService = Get-CimInstance -ClassName Win32_Service -Filter "Name='spooler'" $originalStartupType = (Get-Service -Name spooler).StartType try { $setServiceCommand = [Microsoft.PowerShell.Commands.SetServiceCommand]::new() $setServiceCommand.Name = "Spooler" $setServiceCommand.$parameter = $value $setServiceCommand.Invoke() $updatedService = Get-CimInstance -ClassName Win32_Service -Filter "Name='spooler'" if ($expected -eq $null) { $expected = $value } if ($parameter -eq "StartupType") { $updatedService.StartMode | Should -Be $expected } else { $updatedService.$parameter | Should -Be $expected } } finally { if ($parameter -eq "StartupType") { $setServiceCommand.StartupType = $originalStartupType } else { $setServiceCommand.$parameter = $currentService.$parameter } $setServiceCommand.Invoke() $updatedService = Get-CimInstance -ClassName Win32_Service -Filter "Name='spooler'" $updatedService.$parameter | Should -Be $currentService.$parameter } } It "NewServiceCommand can be used as API for '<parameter>' with '<value>'" -TestCases @( @{parameter = "Name" ; value = "bar"}, @{parameter = "BinaryPathName" ; value = "hello"}, @{parameter = "DisplayName" ; value = "hello world"}, @{parameter = "Description" ; value = "this is a test"}, @{parameter = "StartupType" ; value = "Automatic"}, @{parameter = "StartupType" ; value = "Disabled"}, @{parameter = "StartupType" ; value = "Manual"}, @{parameter = "SecurityDescriptorSddl" ; value = $SecurityDescriptorSddl}, @{parameter = "Credential" ; value = ( [System.Management.Automation.PSCredential]::new("username", #[SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Demo/doc/test secret.")] (ConvertTo-SecureString "PlainTextPassword" -AsPlainText -Force))) } @{parameter = "DependsOn" ; value = "foo", "bar"} ) { param($parameter, $value) $newServiceCommand = [Microsoft.PowerShell.Commands.NewServiceCommand]::new() $newServiceCommand.$parameter = $value $newServiceCommand.$parameter | Should -Be $value } It "Set-Service can change credentials of a service" -Pending { try { $startUsername = "user1" $endUsername = "user2" $servicename = "testsetcredential" $testPass = [Net.NetworkCredential]::new("", (New-ComplexPassword)).SecurePassword $creds = [pscredential]::new(".\$endUsername", $testPass) net user $startUsername $creds.GetNetworkCredential().Password /add > $null net user $endUsername $creds.GetNetworkCredential().Password /add > $null $parameters = @{ Name = $servicename; BinaryPathName = "$PSHOME\pwsh.exe"; StartupType = "Manual"; Credential = $creds } $service = New-Service @parameters $service | Should -Not -BeNullOrEmpty $service = Get-CimInstance Win32_Service -Filter "name='$servicename'" $service.StartName | Should -BeExactly $creds.UserName Set-Service -Name $servicename -Credential $creds $service = Get-CimInstance Win32_Service -Filter "name='$servicename'" $service.StartName | Should -BeExactly $creds.UserName } finally { Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue net user $startUsername /delete > $null net user $endUsername /delete > $null } } It "New-Service can create a new service called '<name>'" -TestCases @( @{name = "testautomatic"; startupType = "Automatic"; description = "foo" ; displayname = "one" ; securityDescriptorSddl = $null}, @{name = "testmanual" ; startupType = "Manual" ; description = "bar" ; displayname = "two" ; securityDescriptorSddl = $SecurityDescriptorSddl}, @{name = "testdisabled" ; startupType = "Disabled" ; description = $null ; displayname = $null ; securityDescriptorSddl = $null}, @{name = "testsddl" ; startupType = "Disabled" ; description = "foo" ; displayname = $null ; securityDescriptorSddl = $SecurityDescriptorSddl} ) { param($name, $startupType, $description, $displayname, $securityDescriptorSddl) try { $parameters = @{ Name = $name; BinaryPathName = "$PSHOME\pwsh.exe"; StartupType = $startupType; } if ($description) { $parameters += @{description = $description} } if ($displayname) { $parameters += @{displayname = $displayname} } if ($securityDescriptorSddl) { $parameters += @{SecurityDescriptorSddl = $securityDescriptorSddl} } $service = New-Service @parameters $service | Should -Not -BeNullOrEmpty $service.displayname | Should -Be $(if($displayname){$displayname}else{$name}) $service.startType | Should -Be $startupType $service = Get-CimInstance Win32_Service -Filter "name='$name'" $service | Should -Not -BeNullOrEmpty $service.Name | Should -Be $name $service.Description | Should -Be $description $expectedStartup = $( switch ($startupType) { "Automatic" {"Auto"} "Manual" {"Manual"} "Disabled" {"Disabled"} default { throw "Unsupported StartupType in TestCases" } } ) $service.StartMode | Should -Be $expectedStartup if ($displayname -eq $null) { $service.DisplayName | Should -Be $name } else { $service.DisplayName | Should -Be $displayname } if ($securityDescriptorSddl) { CheckSecurityDescriptorSddl -SecurityDescriptorSddl $SecurityDescriptorSddl -ServiceName $name } } finally { $service = Get-CimInstance Win32_Service -Filter "name='$name'" if ($service -ne $null) { $service | Remove-CimInstance } } } It "Remove-Service can remove a service" { try { $servicename = "testremoveservice" $parameters = @{ Name = $servicename; BinaryPathName = "$PSHOME\pwsh.exe" } $service = New-Service @parameters $service | Should -Not -BeNullOrEmpty Remove-Service -Name $servicename $service = Get-Service -Name $servicename -ErrorAction SilentlyContinue $service | Should -BeNullOrEmpty } finally { Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue } } It "Remove-Service can accept a ServiceController as pipeline input" { try { $servicename = "testremoveservice" $parameters = @{ Name = $servicename; BinaryPathName = "$PSHOME\pwsh.exe" } $service = New-Service @parameters $service | Should -Not -BeNullOrEmpty Get-Service -Name $servicename | Remove-Service $service = Get-Service -Name $servicename -ErrorAction SilentlyContinue $service | Should -BeNullOrEmpty } finally { Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue } } It "Remove-Service cannot accept a service that does not exist" { { Remove-Service -Name "testremoveservice" -ErrorAction 'Stop' } | Should -Throw -ErrorId "InvalidOperationException,Microsoft.PowerShell.Commands.RemoveServiceCommand" } It "Get-Service can get the '<property>' of a service" -Pending -TestCases @( @{property = "Description"; value = "This is a test description"} @{property = "BinaryPathName"; value = "$PSHOME\powershell.exe";}, @{property = "UserName"; value = $creds.UserName; parameters = @{ Credential = $creds }}, @{property = "StartupType"; value = "AutomaticDelayedStart";} ) { param($property, $value, $parameters) try { $servicename = "testgetservice" $startparameters = @{Name = $servicename; BinaryPathName = "$PSHOME\powershell.exe"} if($parameters -ne $null) { foreach($key in $parameters.Keys) { $startparameters.$key = $parameters.$key } } else { $startparameters.$property = $value } $service = New-Service @startparameters $service | Should -Not -BeNullOrEmpty $service = Get-Service -Name $servicename $service.$property | Should -BeExactly $value } finally { Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue } } It "Set-Service can accept a ServiceController as pipeline input" { try { $servicename = "testsetservice" $newdisplayname = "newdisplayname" $parameters = @{ Name = $servicename; BinaryPathName = "$PSHOME\pwsh.exe" } $service = New-Service @parameters $service | Should -Not -BeNullOrEmpty Get-Service -Name $servicename | Set-Service -DisplayName $newdisplayname $service = Get-Service -Name $servicename $service.DisplayName | Should -BeExactly $newdisplayname } finally { Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue } } It "Set-Service can accept a ServiceController as positional input" { try { $servicename = "testsetservice" $newdisplayname = "newdisplayname" $parameters = @{ Name = $servicename; BinaryPathName = "$PSHOME\pwsh.exe" } $script = { New-Service @parameters | Set-Service -DisplayName $newdisplayname } { & $script } | Should -Not -Throw $service = Get-Service -Name $servicename $service.DisplayName | Should -BeExactly $newdisplayname } finally { Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue } } It "Using bad parameters will fail for '<name>' where '<parameter>' = '<value>'" -TestCases @( @{cmdlet="New-Service"; name = 'credtest' ; parameter = "Credential" ; value = ( [System.Management.Automation.PSCredential]::new("username", #[SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Demo/doc/test secret.")] (ConvertTo-SecureString "PlainTextPassword" -AsPlainText -Force))); errorid = "CouldNotNewService,Microsoft.PowerShell.Commands.NewServiceCommand"}, @{cmdlet="New-Service"; name = 'badstarttype'; parameter = "StartupType"; value = "System"; errorid = "CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.NewServiceCommand"}, @{cmdlet="New-Service"; name = 'winmgmt' ; parameter = "DisplayName"; value = "foo"; errorid = "CouldNotNewService,Microsoft.PowerShell.Commands.NewServiceCommand"}, @{cmdlet="Set-Service"; name = 'winmgmt' ; parameter = "StartupType"; value = "Boot"; errorid = "CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.SetServiceCommand"} ) { param($cmdlet, $name, $parameter, $value, $errorid) $parameters = @{$parameter = $value; Name = $name; ErrorAction = "Stop"} if ($cmdlet -eq "New-Service") { $parameters += @{Binary = "$PSHOME\pwsh.exe"}; } { & $cmdlet @parameters } | Should -Throw -ErrorId $errorid } Context "Set-Service test cases on the services with dependent relationship" { BeforeEach { { Set-Service -Status Running $testservicename2 } | Should -Not -Throw (Get-Service $testservicename1).Status | Should -BeExactly "Running" (Get-Service $testservicename2).Status | Should -BeExactly "Running" } It "Set-Service can stop a service with dependency" { $script = { Set-Service -Status Stopped $testservicename2 -ErrorAction Stop } { & $script } | Should -Not -Throw (Get-Service $testservicename2).Status | Should -BeExactly "Stopped" } It "Set-Service cannot stop a service with running dependent service" { $script = { Set-Service -Status Stopped $testservicename1 -ErrorAction Stop } { & $script } | Should -Throw (Get-Service $testservicename1).Status | Should -BeExactly "Running" (Get-Service $testservicename2).Status | Should -BeExactly "Running" } It "Set-Service can stop a service with running dependent service by parameter -Force" { $script = { Set-Service -Status Stopped -Force $testservicename1 -ErrorAction Stop } { & $script } | Should -Not -Throw (Get-Service $testservicename1).Status | Should -BeExactly "Stopped" (Get-Service $testservicename2).Status | Should -BeExactly "Stopped" } } }