本文介绍了使用备用凭据管理远程服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

-原始帖子-

我正在尝试使用备用凭据。我知道我可以使用当前的凭据使用ServiceController类来管理服务:

I am trying to manage (start/stop) a windows service on a remote machine using alternate credentials. I know that I can use the ServiceController class to manage a service using my current credentials:

Dim sc As New ServiceController(ServiceName, ComputerName)

,但是我想使用其他凭据。我正在使用的其他类(DirectoryEntry和System.Management)都支持使用备用凭据...帮助将不胜感激。

but I want to use different credentials. The other classes I am using (DirectoryEntry and System.Management) both support using alternate credentials... Help would be greatly appreciated.

-工作代码( -

我不得不承认我对此表示怀疑,但下面是代码。我必须对您建议的代码进行较小的更改。每当我尝试使用IPC $时,即使我确定共享存在,它也会返回53个结果代码。因此,在另一个网站的建议下,我删除了共享,只删除了计算机名称,此方法就起作用了。

I have to admit that I was sceptical it would work... but below is the code. I had to make a minor change to the code you suggested. Whenever I tried IPC$ it would return a 53 result code, even though I'm sure the share exists. So at the suggestion of another website I removed the share and just the computer name and this worked.

Imports System.Runtime.InteropServices
Imports System.Net
Imports System.IO
Imports System.ServiceProcess

Module Module1

    Sub Main()
        Dim Computername As String = "SomeComputer"
        'Create connection to remote computer'
        Using nc As New NetworkConnection("\\" + Computername, New NetworkCredential("Domain\User", "Password"))
            Dim sc As New ServiceController("Windows Firewall/Internet Connection Sharing (ICS)", Computername)
            'now we can start/stop/whatever we want here'
        End Using
        Console.ReadLine()
    End Sub

    Public Class NetworkConnection
        Implements IDisposable


        Private _networkName As String

        Public Sub New(ByVal networkName As String, ByVal credentials As NetworkCredential)
            _networkName = networkName

            Dim netResource = New NetResource() With { _
             .Scope = ResourceScope.GlobalNetwork, _
             .ResourceType = ResourceType.Disk, _
             .DisplayType = ResourceDisplaytype.Share, _
             .RemoteName = networkName _
            }

            Dim result = WNetAddConnection2(netResource, credentials.Password, credentials.UserName, 0)

            If result <> 0 Then
                Throw New IOException("Error connecting to remote share", result)
            End If
        End Sub

        Protected Overrides Sub Finalize()
            Try
                Dispose(False)
            Finally
                MyBase.Finalize()
            End Try
        End Sub

        Public Sub Dispose() Implements System.IDisposable.Dispose
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub

        Protected Sub Dispose(ByVal disposing As Boolean)
            WNetCancelConnection2(_networkName, 0, True)
        End Sub

        <DllImport("mpr.dll")> _
        Private Shared Function WNetAddConnection2(ByVal netResource As NetResource, ByVal password As String, ByVal username As String, ByVal flags As Integer) As Integer
        End Function

        <DllImport("mpr.dll")> _
        Private Shared Function WNetCancelConnection2(ByVal name As String, ByVal flags As Integer, ByVal force As Boolean) As Integer
        End Function
    End Class

    <StructLayout(LayoutKind.Sequential)> _
    Public Class NetResource
        Public Scope As ResourceScope
        Public ResourceType As ResourceType
        Public DisplayType As ResourceDisplaytype
        Public Usage As Integer
        Public LocalName As String
        Public RemoteName As String
        Public Comment As String
        Public Provider As String
    End Class

    Public Enum ResourceScope As Integer
        Connected = 1
        GlobalNetwork
        Remembered
        Recent
        Context
    End Enum

    Public Enum ResourceType As Integer
        Any = 0
        Disk = 1
        Print = 2
        Reserved = 8
    End Enum

    Public Enum ResourceDisplaytype As Integer
        Generic = &H0
        Domain = &H1
        Server = &H2
        Share = &H3
        File = &H4
        Group = &H5
        Network = &H6
        Root = &H7
        Shareadmin = &H8
        Directory = &H9
        Tree = &HA
        Ndscontainer = &HB
    End Enum
End Module


推荐答案

要进行远程登录,您应该使用 WNetAddConnection2 (请参阅)或 NetUseAdd (请参见)API。您可以使用 \\RemoteComputer\IPC $ 作为目标资源。

To make remote login you should use WNetAddConnection2 (see http://msdn.microsoft.com/en-us/library/aa385413.aspx) or NetUseAdd (see http://msdn.microsoft.com/en-us/library/aa370645.aspx) API. You can use \\RemoteComputer\IPC$ as the destination resource.

UPDATED ,基于评论中的问题:关于IPC $会话的解释可能很长。只是主要信息。

UPDATED based on the question from the comment: The explanation about IPC$ sessions can be long. Just the main information.

如果要在远程计算机上执行某些操作,首先要做的是建立与远程计算机的经过身份验证的连接。远程计算机上的网络登录远程登录)将完成,这与本地登录完全一样。网络登录会话保持不变,如果您与例如 \\RemoteComputer\share1 和您计算机上的其他程序的连接,请尝试进行访问,例如 \\RemoteComputer\share2 ,将使用相同的会话。

If you want to do something on a remote computer the first thing which will be done is the establishing a authenticated "connection" to the remote computer. The network login (remote login) on the remote computer will be done, which works quite other as a local login. The network logon session stay holding and if you have a connection to for example \\RemoteComputer\share1 and one other program on your computer try access for example \\RemoteComputer\share2, the same session will be used.

您可以使用<$ c模拟情况$ c> net.exe 。只需启动 cmd.exe 并输入

You can simulate the situation with net.exe. Just start cmd.exe and type

net use \\RemoteComputer\IPC$ /u:Domain\User password

net use \\RemoteComputer\IPC$ /u:RemoteComputer\LocalRemoteUser password

然后您将连接到目标计算机。然后,您可以在资源管理器中键入 \\RemoteComputer\AnyShare ,并在用户的 Domain\User 或 RemoteComputer\LocalRemoteUser 凭据。要断开连接使用

then you will have a connection to the destination computer. Then you can type \\RemoteComputer\AnyShare in Explorer and access file system under the user's Domain\User or RemoteComputer\LocalRemoteUser credential. To disconnect use

net use \\RemoteComputer\IPC /d

如果尝试在远程计算机上启动/停止服务,则将尝试建立相同的IPC会话。如果您已经使用用户凭据之一进行了此类会话,则将使用该会话。功能 WNetAddConnection2 NetUseAdd 可以替代网络使用。如果您要永久使用其他用户的凭据访问远程计算机,则可以使用 CredWrite CredWriteDomainCredentials CredUIPromptForCredentials / CredUIPromptForWindowsCredentials 。 Cred函数似乎不是解决您问题的最佳方法。

If you try to start/stop a service on the remote computer the same IPC session will be tried to established. If you have already such session with one of user's credentials it will be used. Functions WNetAddConnection2, NetUseAdd can be used as replacement of "net use". If you permanently want to access a remote computer with other user's credentials you can use CredWrite, CredWriteDomainCredentials or CredUIPromptForCredentials / CredUIPromptForWindowsCredentials. The Cred-function seems me not the best way for your case.

这篇关于使用备用凭据管理远程服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 17:54