【问题标题】:How to create a Windows Service in Powershell for "Network Service" account?如何在 Powershell 中为“网络服务”帐户创建 Windows 服务?
【发布时间】:2013-01-20 10:56:55
【问题描述】:

我想使用 Powershell 创建一个 Windows 服务。为给定的用户创建它是小菜一碟。我用这个函数改编自here

function ReinstallService1 ($serviceName, $binaryPath, $login, $pass)
{  
    Write-Host "installing service"
    # creating credentials which can be used to run my windows service
    $secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force
    $mycreds = New-Object System.Management.Automation.PSCredential ($login, $secpasswd)

    # creating widnows service using all provided parameters
    New-Service -name $serviceName -binaryPathName $binaryPath -displayName $serviceName -startupType Automatic -credential $mycreds
    Write-Host "installation completed"
}

我的问题是:如何创建“网络服务”帐户?

如果我修改 New-Service 行并删除凭据参数,则会为 “本地系统” 帐户创建服务。差点错过。

New-Service -name $serviceName -binaryPathName $binaryPath -displayName $serviceName -startupType Automatic 

我在 Google 上搜索了很多,但没有发现任何指示服务帐户的方法。如果我尝试为用户 “NETWORK SSERVICE” 使用 Credential 参数,我不知道要输入什么密码,如果我发明了一个(以防 cmdlet 忽略它)它不起作用。错误是:

新服务:服务'XXXX(XXXX)' 由于以下错误无法创建:帐户名称是 无效或不存在,或该帐户的密码无效 指定名称

【问题讨论】:

  • 您能分享您的确切新服务热线吗?当我使用这样的东西时: New-Service -name $serviceName -binaryPathName $path -displayName $serviceName -startupType Automatic -Credential "NT AUTHORITY\NETWORK SERVICE" 我收到密码提示。
  • 问题是您在 -Credential 中只传递了用户名。我的线路和你的一样,但我通过 -Credential $MyCreds $MyCreds value is: $MyCreds= $mycreds = New-Object System.Management.Automation.PSCredential ($login, $secpasswd) $login value is "NT AUTHORITY\NETWORK SERVICE " $secpassword 可以是任何东西。
  • @Aniket,我已经在脚本的最终版本中添加了一个答案,所以你可以比我的评论更好地看到它......

标签: powershell windows-7 windows-services


【解决方案1】:

帐户的正确名称是NT AUTHORITY\NETWORK SERVICE

【讨论】:

  • 不,这不是正确的名称,正确的名称取决于您正在执行的系统的语言,可以像这样找到:$SID = [System.Security.Principal.WellKnownSidType ]::NetworkServiceSid $Account = new-object system.security.principal.securityidentifier($SID, $null) $NetworkServiceName = $Account.Translate([system.security.principal.ntaccount]).value
【解决方案2】:

这是重新安装服务的最终版本,为所有人谋福利,特别是针对 Aniket。

function ReinstallService ($serviceName, $binaryPath, $description, $login, $password, $startUpType)
{
        Write-Host "Trying to create service: $serviceName"

        #Check Parameters
        if ((Test-Path $binaryPath)-eq $false)
        {
            Write-Host "BinaryPath to service not found: $binaryPath"
            Write-Host "Service was NOT installed."
            return
        }

        if (("Automatic", "Manual", "Disabled") -notcontains $startUpType)
        {
            Write-Host "Value for startUpType parameter should be (Automatic or Manual or Disabled) and it was $startUpType"
            Write-Host "Service was NOT installed."
            return
        }

        # Verify if the service already exists, and if yes remove it first
        if (Get-Service $serviceName -ErrorAction SilentlyContinue)
        {
            # using WMI to remove Windows service because PowerShell does not have CmdLet for this
            $serviceToRemove = Get-WmiObject -Class Win32_Service -Filter "name='$serviceName'"

            $serviceToRemove.delete()
            Write-Host "Service removed: $serviceName"
        }

        # if password is empty, create a dummy one to allow have credentias for system accounts: 
        #NT AUTHORITY\LOCAL SERVICE
        #NT AUTHORITY\NETWORK SERVICE
        if ($password -eq "") 
        {
            #$secpassword = (new-object System.Security.SecureString)
            # Bug detected by @GaTechThomas
            $secpasswd = (new-object System.Security.SecureString)
        }
        else
        {
            $secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
        }
        $mycreds = New-Object System.Management.Automation.PSCredential ($login, $secpasswd)

        # Creating Windows Service using all provided parameters
        Write-Host "Installing service: $serviceName"
        New-Service -name $serviceName -binaryPathName $binaryPath -Description $description -displayName $serviceName -startupType $startUpType -credential $mycreds

        Write-Host "Installation completed: $serviceName"

        # Trying to start new service
        Write-Host "Trying to start new service: $serviceName"
        $serviceToStart = Get-WmiObject -Class Win32_Service -Filter "name='$serviceName'"
        $serviceToStart.startservice()
        Write-Host "Service started: $serviceName"

        #SmokeTest
        Write-Host "Waiting 5 seconds to give time service to start..."
        Start-Sleep -s 5
        $SmokeTestService = Get-Service -Name $serviceName
        if ($SmokeTestService.Status -ne "Running")
        {
            Write-Host "Smoke test: FAILED. (SERVICE FAILED TO START)"
            Throw "Smoke test: FAILED. (SERVICE FAILED TO START)"
        }
        else
        {
            Write-Host "Smoke test: OK."
        }

}

【讨论】:

  • 这可能会产生奇怪的副作用,如果用户的密码是dummy,而调用者没有提供密码,它就可以工作。
  • This answer 提供了一种创建空SecureString 的方法。
  • 此代码中的错误:$secpassword 应为 $secpasswd
【解决方案3】:

您可以像这样直接获得网络服务的信誉:

$login = "NT AUTHORITY\NETWORK SERVICE"
#### #just set a dummy psw since it's just used to get credentials

$psw = "dummy"

$scuritypsw = ConvertTo-SecureString $psw -AsPlainText -Force

$mycreds = New-Object System.Management.Automation.PSCredential($login, $scuritypsw)
#### #then you can use the cred to new a windows service

$serviceName = "Test"
$binaryPath = "C:\Test\Test.exe"

New-Service -name $serviceName -binaryPathName $binaryPath -displayName $serviceName -startupType Automatic -credential $mycreds

【讨论】:

    【解决方案4】:

    Get-WmiObject 现已弃用。但是,PowerShell 现在已内置 cmdlet 以使用服务。以下是 Oscar Foley 的答案中 ReinstallService 的更新版本,相应地调整了方便的默认值和用于启动和停止服务的包装器:

    # https://stackoverflow.com/questions/35064964/powershell-script-to-check-if-service-is-started-if-not-then-start-it
    function TryStopService([string] $serviceName)
    {
        Write-Host "Attempting to stop service: $serviceName..."
        $service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
    
        if($service)
        {
            if ($service.Status -ne 'Running')
            {
                Write-Host "    Service: $serviceName is not running."
            }
            else
            {
                Stop-Service -name $serviceName
                Write-Host "    Stopped service: $serviceName."
            }
        }
        else
        {
            Write-Host "    Service: $serviceName is not found."
        }
    }
    
    function UninstallService([string] $serviceName)
    {
        Write-Host "Attempting to uninstall service: $serviceName..."
        if (Get-Service $serviceName -ErrorAction SilentlyContinue)
        {
            Remove-Service -Name $serviceName
            Write-Host "    Uninstalled service: $serviceName."
        }
        else
        {
            Write-Host "    Service: $serviceName is not found."
        }
    }
    
    function StartSertice([string] $serviceName)
    {
        Write-Host "Attempting to start service: $serviceName..."
        $service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
    
        if($service)
        {
            if ($service.Status -eq 'Running')
            {
                Write-Host "    Service: $serviceName is already running."
                return
            }
        }
    
        # Trying to start new service.
        Write-Host "    Trying to start new service: $serviceName."
        Start-Service -Name $serviceName
    
        #Check that service has started.
        Write-Host "    Waiting 5 seconds to give service time to start..."
        Start-Sleep -s 5
        $testService = Get-Service -Name $serviceName
    
        if ($testService.Status -ne "Running")
        {
            [string] $errMessage = "    Failed to start service: $serviceName"
            Write-Host $errMessage
            Throw $errMessage
        }
        else
        {
            Write-Host "    Started service: $serviceName."
        }
    }
    
    function ReinstallService ([string] $serviceName, [string] $binaryPath, [string] $description = "", [string] $login = "NT AUTHORITY\NETWORK SERVICE", [string] $password = "", [string] $startUpType = "Automatic")
    {
        Write-Host "Attempting to reinstall service: $serviceName..."
    
        #Check Parameters
        if ((Test-Path $binaryPath)-eq $false)
        {
            Write-Host "    BinaryPath to service was not found: $binaryPath."
            Write-Host "    Service was NOT installed."
            return
        }
    
        if (("Automatic", "Manual", "Disabled") -notcontains $startUpType)
        {
            Write-Host "    Value for startUpType parameter should be (Automatic or Manual or Disabled) and it was $startUpType"
            Write-Host "    Service was NOT installed."
            return
        }
    
        TryStopService -serviceName $serviceName
        UninstallService -serviceName $serviceName
    
        # if password is empty, create a dummy one to allow having credentias for system accounts:
        #     NT AUTHORITY\LOCAL SERVICE
        #     NT AUTHORITY\NETWORK SERVICE
        if ($password -eq "")
        {
            $secpassword = (new-object System.Security.SecureString)
        }
        else
        {
            $secpassword = ConvertTo-SecureString $password -AsPlainText -Force
        }
    
        $mycreds = New-Object System.Management.Automation.PSCredential ($login, $secpassword)
    
        # Creating Windows Service using all provided parameters.
        Write-Host "Installing service: $serviceName with user name: '$login'..."
        New-Service -name $serviceName -binaryPathName $binaryPath -Description $description -displayName $serviceName -startupType $startUpType -credential $mycreds
        Write-Host "    Installed service: $serviceName."
    
        # Trying to start new service.
        StartSertice -serviceName $serviceName
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-30
      • 2016-04-14
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多