Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
Set-Service.Tests.ps1426 linesDownload Raw Back to Microsoft.PowerShell.Management
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3 4[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')]5param()6 7Import-Module (Join-Path -Path $PSScriptRoot '..\Microsoft.PowerShell.Security\certificateCommon.psm1')8 9Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows" {10    BeforeAll {11        $originalDefaultParameterValues = $PSDefaultParameterValues.Clone()12        if ( -not $IsWindows ) {13            $PSDefaultParameterValues["it:skip"] = $true14        }15        if ($IsWindows) {16            $userName = "testuserservices"17            $testPass = [Net.NetworkCredential]::new("", (New-ComplexPassword)).SecurePassword18            $creds    = [pscredential]::new(".\$userName", $testPass)19            $SecurityDescriptorSddl = 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;SU)'20            $WrongSecurityDescriptorSddl = 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BB)(A;;CCLCSWLOCRRC;;;SU)'21            net user $userName $creds.GetNetworkCredential().Password /add > $null22 23            $testservicename1 = "testservice1"24            $testservicename2 = "testservice2"25            $svcbinaryname    = "TestService"26            $svccmd = Get-Command $svcbinaryname27            $svccmd | Should -Not -BeNullOrEmpty28            $svcfullpath = $svccmd.Path29            $testservice1 = New-Service -BinaryPathName $svcfullpath -Name $testservicename130            $testservice1 | Should -Not -BeNullOrEmpty31            $testservice2 = New-Service -BinaryPathName $svcfullpath -Name $testservicename2 -DependsOn $testservicename132            $testservice2 | Should -Not -BeNullOrEmpty33        }34 35        Function CheckSecurityDescriptorSddl {36            Param(37                [Parameter(Mandatory)]38                $SecurityDescriptorSddl,39 40                [Parameter(Mandatory)]41                $ServiceName42            )43            $Counter      = 044            $ExpectedSDDL = ConvertFrom-SddlString -Sddl $SecurityDescriptorSddl45 46            # Selecting the first item in the output array as below command gives plain text output from the native sc.exe.47            $UpdatedSDDL  = ConvertFrom-SddlString -Sddl (sc sdshow $ServiceName)[1]48 49            $UpdatedSDDL.Owner | Should -Be $ExpectedSDDL.Owner50            $UpdatedSDDL.Group | Should -Be $ExpectedSDDL.Group51            $UpdatedSDDL.DiscretionaryAcl.Count | Should -Be $ExpectedSDDL.DiscretionaryAcl.Count52            $UpdatedSDDL.DiscretionaryAcl | ForEach-Object -Process {53                $_ | Should -Be $ExpectedSDDL.DiscretionaryAcl[$Counter]54                $Counter++55            }56        }57    }58    AfterAll {59        $global:PSDefaultParameterValues = $originalDefaultParameterValues60        if ($IsWindows) {61            net user $userName /delete > $null62 63            Stop-Service $testservicename264            Stop-Service $testservicename165            Remove-Service $testservicename266            Remove-Service $testservicename167        }68    }69 70    It "SetServiceCommand can be used as API for '<parameter>' with '<value>'" -TestCases @(71        @{parameter = "Name"        ; value = "bar"},72        @{parameter = "DisplayName" ; value = "hello"},73        @{parameter = "Description" ; value = "hello world"},74        @{parameter = "StartupType" ; value = "Automatic"},75        @{parameter = "StartupType" ; value = "Disabled"},76        @{parameter = "StartupType" ; value = "Manual"},77        @{parameter = "Status"      ; value = "Running"},78        @{parameter = "Status"      ; value = "Stopped"},79        @{parameter = "Status"      ; value = "Paused"},80        @{parameter = "InputObject" ; script = {Get-Service | Select-Object -First 1}},81        # cmdlet inherits this property, but it's not exposed as parameter so it should be $null82        @{parameter = "Include"     ; value = "foo", "bar" ; expectedNull = $true},83        # cmdlet inherits this property, but it's not exposed as parameter so it should be $null84        @{parameter = "Exclude"     ; value = "foo", "bar" ; expectedNull = $true}85    ) {86        param($parameter, $value, $script, $expectedNull)87 88        $setServiceCommand = [Microsoft.PowerShell.Commands.SetServiceCommand]::new()89        if ($script -ne $null) {90            $value = & $script91        }92        $setServiceCommand.$parameter = $value93        if ($expectedNull -eq $true) {94            $setServiceCommand.$parameter | Should -BeNullOrEmpty95        }96        else {97            $setServiceCommand.$parameter | Should -Be $value98        }99    }100 101    It "Set-Service parameter validation for invalid values: <script>" -TestCases @(102        @{103            script  = {Set-Service foo -StartupType bar -ErrorAction Stop};104            errorid = "CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.SetServiceCommand"105        },106        @{107            script  = {Set-Service -Name $testservicename1 -SecurityDescriptorSddl $WrongSecurityDescriptorSddl };108            errorid = "System.ArgumentException,Microsoft.PowerShell.Commands.SetServiceCommand"109        }110    ) {111        param($script, $errorid)112        { & $script } | Should -Throw -ErrorId $errorid113    }114 115 116    It "Sets securitydescriptor of service using Set-Service " {117        Set-Service -Name $TestServiceName1 -SecurityDescriptorSddl $SecurityDescriptorSddl118        CheckSecurityDescriptorSddl -SecurityDescriptor $SecurityDescriptorSddl -ServiceName $TestServiceName1119    }120 121    It "Set-Service can change '<parameter>' to '<value>'" -TestCases @(122        @{parameter = "Description"; value = "hello"},123        @{parameter = "DisplayName"; value = "test spooler"},124        @{parameter = "StartupType"; value = "Disabled"},125        @{parameter = "Status"     ; value = "running"     ; expected = "OK"}126    ) {127        param($parameter, $value, $expected)128        $currentService = Get-CimInstance -ClassName Win32_Service -Filter "Name='spooler'"129        $originalStartupType = (Get-Service -Name spooler).StartType130        try {131            $setServiceCommand = [Microsoft.PowerShell.Commands.SetServiceCommand]::new()132            $setServiceCommand.Name = "Spooler"133            $setServiceCommand.$parameter = $value134            $setServiceCommand.Invoke()135            $updatedService = Get-CimInstance -ClassName Win32_Service -Filter "Name='spooler'"136            if ($expected -eq $null) {137                $expected = $value138            }139            if ($parameter -eq "StartupType") {140                $updatedService.StartMode | Should -Be $expected141            }142            else {143                $updatedService.$parameter | Should -Be $expected144            }145        }146        finally {147            if ($parameter -eq "StartupType") {148                $setServiceCommand.StartupType = $originalStartupType149            }150            else {151                $setServiceCommand.$parameter = $currentService.$parameter152            }153            $setServiceCommand.Invoke()154            $updatedService = Get-CimInstance -ClassName Win32_Service -Filter "Name='spooler'"155            $updatedService.$parameter | Should -Be $currentService.$parameter156        }157    }158 159    It "NewServiceCommand can be used as API for '<parameter>' with '<value>'" -TestCases @(160        @{parameter = "Name"                   ; value = "bar"},161        @{parameter = "BinaryPathName"         ; value = "hello"},162        @{parameter = "DisplayName"            ; value = "hello world"},163        @{parameter = "Description"            ; value = "this is a test"},164        @{parameter = "StartupType"            ; value = "Automatic"},165        @{parameter = "StartupType"            ; value = "Disabled"},166        @{parameter = "StartupType"            ; value = "Manual"},167        @{parameter = "SecurityDescriptorSddl" ; value = $SecurityDescriptorSddl},168        @{parameter = "Credential"             ; value = (169                [System.Management.Automation.PSCredential]::new("username",170                    #[SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Demo/doc/test secret.")]171                    (ConvertTo-SecureString "PlainTextPassword" -AsPlainText -Force)))172        }173        @{parameter = "DependsOn"      ; value = "foo", "bar"}174    ) {175        param($parameter, $value)176 177        $newServiceCommand = [Microsoft.PowerShell.Commands.NewServiceCommand]::new()178        $newServiceCommand.$parameter = $value179        $newServiceCommand.$parameter | Should -Be $value180    }181 182    It "Set-Service can change credentials of a service" -Pending {183        try {184            $startUsername = "user1"185            $endUsername = "user2"186            $servicename = "testsetcredential"187            $testPass = [Net.NetworkCredential]::new("", (New-ComplexPassword)).SecurePassword188            $creds = [pscredential]::new(".\$endUsername", $testPass)189            net user $startUsername $creds.GetNetworkCredential().Password /add > $null190            net user $endUsername $creds.GetNetworkCredential().Password /add > $null191            $parameters = @{192                Name           = $servicename;193                BinaryPathName = "$PSHOME\pwsh.exe";194                StartupType    = "Manual";195                Credential     = $creds196            }197            $service = New-Service @parameters198            $service | Should -Not -BeNullOrEmpty199            $service = Get-CimInstance Win32_Service -Filter "name='$servicename'"200            $service.StartName | Should -BeExactly $creds.UserName201 202            Set-Service -Name $servicename -Credential $creds203            $service = Get-CimInstance Win32_Service -Filter "name='$servicename'"204            $service.StartName | Should -BeExactly $creds.UserName205        }206        finally {207            Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue208            net user $startUsername /delete > $null209            net user $endUsername /delete > $null210        }211    }212 213    It "New-Service can create a new service called '<name>'" -TestCases @(214        @{name = "testautomatic"; startupType = "Automatic"; description = "foo" ; displayname = "one" ; securityDescriptorSddl = $null},215        @{name = "testmanual"   ; startupType = "Manual"   ; description = "bar" ; displayname = "two" ; securityDescriptorSddl = $SecurityDescriptorSddl},216        @{name = "testdisabled" ; startupType = "Disabled" ; description = $null ; displayname = $null ; securityDescriptorSddl = $null},217        @{name = "testsddl"     ; startupType = "Disabled" ; description = "foo" ; displayname = $null ; securityDescriptorSddl = $SecurityDescriptorSddl}218    ) {219        param($name, $startupType, $description, $displayname, $securityDescriptorSddl)220        try {221            $parameters = @{222                Name           = $name;223                BinaryPathName = "$PSHOME\pwsh.exe";224                StartupType    = $startupType;225            }226            if ($description) {227                $parameters += @{description = $description}228            }229            if ($displayname) {230                $parameters += @{displayname = $displayname}231            }232            if ($securityDescriptorSddl) {233                $parameters += @{SecurityDescriptorSddl = $securityDescriptorSddl}234            }235 236            $service = New-Service @parameters237            $service | Should -Not -BeNullOrEmpty238            $service.displayname | Should -Be $(if($displayname){$displayname}else{$name})239            $service.startType | Should -Be $startupType240 241            $service = Get-CimInstance Win32_Service -Filter "name='$name'"242            $service | Should -Not -BeNullOrEmpty243            $service.Name | Should -Be $name244            $service.Description | Should -Be $description245            $expectedStartup = $(246                switch ($startupType) {247                    "Automatic" {"Auto"}248                    "Manual" {"Manual"}249                    "Disabled" {"Disabled"}250                    default { throw "Unsupported StartupType in TestCases" }251                }252            )253            $service.StartMode | Should -Be $expectedStartup254            if ($displayname -eq $null) {255                $service.DisplayName | Should -Be $name256            }257            else {258                $service.DisplayName | Should -Be $displayname259            }260            if ($securityDescriptorSddl) {261                CheckSecurityDescriptorSddl -SecurityDescriptorSddl $SecurityDescriptorSddl -ServiceName $name262            }263        }264        finally {265            $service = Get-CimInstance Win32_Service -Filter "name='$name'"266            if ($service -ne $null) {267                $service | Remove-CimInstance268            }269        }270    }271 272    It "Remove-Service can remove a service" {273        try {274            $servicename = "testremoveservice"275            $parameters = @{276                Name           = $servicename;277                BinaryPathName = "$PSHOME\pwsh.exe"278            }279            $service = New-Service @parameters280            $service | Should -Not -BeNullOrEmpty281            Remove-Service -Name $servicename282            $service = Get-Service -Name $servicename -ErrorAction SilentlyContinue283            $service | Should -BeNullOrEmpty284        }285        finally {286            Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue287        }288    }289 290    It "Remove-Service can accept a ServiceController as pipeline input" {291        try {292            $servicename = "testremoveservice"293            $parameters = @{294                Name           = $servicename;295                BinaryPathName = "$PSHOME\pwsh.exe"296            }297            $service = New-Service @parameters298            $service | Should -Not -BeNullOrEmpty299            Get-Service -Name $servicename | Remove-Service300            $service = Get-Service -Name $servicename -ErrorAction SilentlyContinue301            $service | Should -BeNullOrEmpty302        }303        finally {304            Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue305        }306    }307 308    It "Remove-Service cannot accept a service that does not exist" {309        { Remove-Service -Name "testremoveservice" -ErrorAction 'Stop' } | Should -Throw -ErrorId "InvalidOperationException,Microsoft.PowerShell.Commands.RemoveServiceCommand"310    }311 312    It "Get-Service can get the '<property>' of a service" -Pending -TestCases @(313        @{property = "Description";    value = "This is a test description"}314        @{property = "BinaryPathName"; value = "$PSHOME\powershell.exe";},315        @{property = "UserName";       value = $creds.UserName; parameters = @{ Credential = $creds }},316        @{property = "StartupType";    value = "AutomaticDelayedStart";}317        ) {318            param($property, $value, $parameters)319            try {320            $servicename = "testgetservice"321            $startparameters = @{Name = $servicename; BinaryPathName = "$PSHOME\powershell.exe"}322            if($parameters -ne $null) {323                foreach($key in $parameters.Keys) {324                $startparameters.$key = $parameters.$key325                }326            } else {327                $startparameters.$property = $value328            }329            $service = New-Service @startparameters330            $service | Should -Not -BeNullOrEmpty331            $service = Get-Service -Name $servicename332            $service.$property | Should -BeExactly $value333        }334        finally {335            Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue336        }337    }338 339    It "Set-Service can accept a ServiceController as pipeline input" {340        try {341            $servicename = "testsetservice"342            $newdisplayname = "newdisplayname"343            $parameters = @{344                Name           = $servicename;345                BinaryPathName = "$PSHOME\pwsh.exe"346            }347            $service = New-Service @parameters348            $service | Should -Not -BeNullOrEmpty349            Get-Service -Name $servicename | Set-Service -DisplayName $newdisplayname350            $service = Get-Service -Name $servicename351            $service.DisplayName | Should -BeExactly $newdisplayname352        }353        finally {354            Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue355        }356    }357 358    It "Set-Service can accept a ServiceController as positional input" {359        try {360            $servicename = "testsetservice"361            $newdisplayname = "newdisplayname"362            $parameters = @{363                Name           = $servicename;364                BinaryPathName = "$PSHOME\pwsh.exe"365            }366 367            $script = { New-Service @parameters | Set-Service -DisplayName $newdisplayname }368            { & $script } | Should -Not -Throw369            $service = Get-Service -Name $servicename370            $service.DisplayName | Should -BeExactly $newdisplayname371        }372        finally {373            Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue374        }375    }376 377    It "Using bad parameters will fail for '<name>' where '<parameter>' = '<value>'" -TestCases @(378        @{cmdlet="New-Service"; name = 'credtest'    ; parameter = "Credential" ; value = (379            [System.Management.Automation.PSCredential]::new("username",380            #[SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="Demo/doc/test secret.")]381            (ConvertTo-SecureString "PlainTextPassword" -AsPlainText -Force)));382            errorid = "CouldNotNewService,Microsoft.PowerShell.Commands.NewServiceCommand"},383        @{cmdlet="New-Service"; name = 'badstarttype'; parameter = "StartupType"; value = "System";384            errorid = "CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.NewServiceCommand"},385        @{cmdlet="New-Service"; name = 'winmgmt'     ; parameter = "DisplayName"; value = "foo";386            errorid = "CouldNotNewService,Microsoft.PowerShell.Commands.NewServiceCommand"},387        @{cmdlet="Set-Service"; name = 'winmgmt'     ; parameter = "StartupType"; value = "Boot";388            errorid = "CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.SetServiceCommand"}389    ) {390        param($cmdlet, $name, $parameter, $value, $errorid)391        $parameters = @{$parameter = $value; Name = $name; ErrorAction = "Stop"}392        if ($cmdlet -eq "New-Service") {393            $parameters += @{Binary = "$PSHOME\pwsh.exe"};394        }395        { & $cmdlet @parameters } | Should -Throw -ErrorId $errorid396    }397 398    Context "Set-Service test cases on the services with dependent relationship" {399        BeforeEach {400            { Set-Service -Status Running $testservicename2 } | Should -Not -Throw401            (Get-Service $testservicename1).Status | Should -BeExactly "Running"402            (Get-Service $testservicename2).Status | Should -BeExactly "Running"403        }404 405        It "Set-Service can stop a service with dependency" {406            $script = { Set-Service -Status Stopped $testservicename2 -ErrorAction Stop }407            { & $script } | Should -Not -Throw408            (Get-Service $testservicename2).Status | Should -BeExactly "Stopped"409        }410 411        It "Set-Service cannot stop a service with running dependent service" {412            $script = { Set-Service -Status Stopped $testservicename1 -ErrorAction Stop }413            { & $script } | Should -Throw414            (Get-Service $testservicename1).Status | Should -BeExactly "Running"415            (Get-Service $testservicename2).Status | Should -BeExactly "Running"416        }417 418        It "Set-Service can stop a service with running dependent service by parameter -Force" {419            $script = { Set-Service -Status Stopped -Force $testservicename1 -ErrorAction Stop }420            { & $script } | Should -Not -Throw421            (Get-Service $testservicename1).Status | Should -BeExactly "Stopped"422            (Get-Service $testservicename2).Status | Should -BeExactly "Stopped"423        }424    }425}426