Added functionality to set credientials on Set-Service command (#4844)

Now we can specifiy the -Credential parameter on Set-Service cmdlet to change a service's logon account.
This commit is contained in:
Jonas Andersen
2017-09-18 14:23:17 +04:00
committed by Ilya
parent 03e3257b0a
commit b7ec5da216
2 changed files with 57 additions and 4 deletions
@@ -1466,6 +1466,14 @@ namespace Microsoft.PowerShell.Commands
}
internal string displayName = null;
/// <summary>
/// Account under which the service should run
/// </summary>
/// <value></value>
[Parameter]
[Credential()]
public PSCredential Credential { get; set; }
/// <summary>
@@ -1587,6 +1595,7 @@ namespace Microsoft.PowerShell.Commands
{
ServiceController service = null;
string ServiceComputerName = null;
IntPtr password = IntPtr.Zero;
foreach (string computer in ComputerName)
{
bool objServiceShouldBeDisposed = false;
@@ -1677,9 +1686,9 @@ namespace Microsoft.PowerShell.Commands
continue;
}
// modify startup type or display name
// Modify startup type or display name or credential
if (!String.IsNullOrEmpty(DisplayName)
|| (ServiceStartMode)(-1) != StartupType)
|| (ServiceStartMode)(-1) != StartupType || null != Credential)
{
DWORD dwStartType = NativeMethods.SERVICE_NO_CHANGE;
if (!NativeMethods.TryGetNativeStartupType(StartupType, out dwStartType))
@@ -1690,6 +1699,13 @@ namespace Microsoft.PowerShell.Commands
ErrorCategory.InvalidArgument);
return;
}
string username = null;
if (null != Credential)
{
username = Credential.UserName;
password = Marshal.SecureStringToCoTaskMemUnicode(Credential.Password);
}
bool succeeded = NativeMethods.ChangeServiceConfigW(
hService,
NativeMethods.SERVICE_NO_CHANGE,
@@ -1699,8 +1715,8 @@ namespace Microsoft.PowerShell.Commands
null,
IntPtr.Zero,
null,
null,
IntPtr.Zero,
username,
password,
DisplayName
);
if (!succeeded)
@@ -1836,6 +1852,10 @@ namespace Microsoft.PowerShell.Commands
} //End try
finally
{
if (IntPtr.Zero != password)
{
Marshal.ZeroFreeCoTaskMemUnicode(password);
}
if (objServiceShouldBeDisposed)
{
service.Dispose();
@@ -114,6 +114,39 @@ Describe "Set/New-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows"
$newServiceCommand.$parameter | Should Be $value
}
It "Set-Service can change credentials of a service" {
try {
$startUsername = "user1"
$endUsername = "user2"
$testPass = "Secret123!"
$servicename = "testsetcredential"
net user $startUsername $testPass /add > $null
net user $endUsername $testPass /add > $null
$password = ConvertTo-SecureString $testPass -AsPlainText -Force
$creds = [pscredential]::new(".\$startUsername", $password)
$parameters = @{
Name = $servicename;
BinaryPathName = "$PSHOME\powershell.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
$creds = [pscredential]::new(".\$endUsername", $password)
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"},
@{name = "testmanual" ; startupType = "Manual" ; description = "bar" ; displayname = "two"},