Mapear uma unidade de rede para ser usada por um serviço

213

Suponha que algum serviço do Windows use código que queira unidades de rede mapeadas e nenhum caminho UNC. Como posso disponibilizar o mapeamento da unidade para a sessão do serviço quando o serviço é iniciado? Efetuar login como usuário do serviço e criar um mapeamento persistente não estabelecerá o mapeamento no contexto do serviço real.

VoidPointer
fonte
6
Veja a resposta do ForcePush, sua solução alternativa funciona.
Ubikuity 26/08/11

Respostas:

44

Você precisará modificar o serviço ou envolvê-lo em um processo auxiliar: além dos problemas de acesso à sessão / unidade, os mapeamentos de unidade persistentes são restaurados apenas em um logon interativo, que os serviços normalmente não executam.

A abordagem do processo auxiliar pode ser bastante simples: basta criar um novo serviço que mapeie a unidade e inicie o serviço 'real'. As únicas coisas que não são inteiramente triviais sobre isso são:

  • O serviço auxiliar precisará transmitir todos os comandos SCM apropriados (iniciar / parar, etc.) para o serviço real. Se o serviço real aceitar comandos SCM personalizados, lembre-se de transmiti-los também (não espero que um serviço que considere os caminhos UNC exóticos use esses comandos ...)

  • As coisas podem ficar um pouco complicadas em termos de credenciais. Se o serviço real for executado em uma conta de usuário normal, você também poderá executar o serviço auxiliar nessa conta e tudo ficará bem, desde que a conta tenha acesso adequado ao compartilhamento de rede. Se o serviço real só funcionar quando executado como LOCALSYSTEM ou algo assim, as coisas ficarão mais interessantes, pois não poderão "ver" a unidade de rede, ou exigirão algum malabarismo com credenciais para fazer as coisas funcionarem.

mdb
fonte
2
Muito informativo ... Estou correto ao supor que os scripts de logon também sejam executados apenas para sessões de logon interativo e não para sessões de serviço?
VoidPointer 8/08
220

Use isso a seu próprio risco. (Eu testei no XP e no Server 2008 x64 R2)

Para esse hack, você precisará do SysinternalsSuite de Mark Russinovich :

Etapa 1: Abrir um prompt elevado do cmd.exe (Executar como administrador)

Etapa 2: Elevar novamente para fazer root usando o PSExec.exe: Navegue até a pasta que contém o SysinternalsSuite e execute o seguinte comando psexec -i -s cmd.exe : agora você está dentro de um prompt nt authority\systeme pode provar isso digitando whoami. Isso -ié necessário porque os mapeamentos de unidades precisam interagir com o usuário

Etapa 3: Criar a unidade mapeada persistente como a conta SYSTEM com o seguinte comando net use z: \\servername\sharedfolder /persistent:yes

É tão fácil!

AVISO : Você só pode remover esse mapeamento da mesma maneira que o criou da conta SYSTEM. Se você precisar removê-lo, siga as etapas 1 e 2, mas altere o comando na etapa 3 para net use z: /delete.

NOTA : A unidade mapeada recém-criada agora será exibida para TODOS os usuários deste sistema, mas será exibida como "Unidade de rede desconectada (Z :)". Não deixe o nome enganar você. Pode alegar estar desconectado, mas funcionará para todos. É assim que você pode dizer que esse hack não é suportado por M $.

ForcePush
fonte
3
Eu estava tentando usar esta solução e me deparei com este problema: a unidade mapeada aparece desconectada dos usuários (mesmo administradores). Alguma sugestão?
Constantin Baciu
7
Após uma reinicialização, a unidade mapeada se foi. ? Todas as ideias O mapeamento é mantido, mas o status é "indisponível" para que ele não aparecer
Tommy
4
Também vejo o mapeamento indisponível após uma reinicialização.
Dave Patterson
33
Para fazê-lo funcionar após uma reinicialização, crie um script que contenha apenas net use z: \\servername\sharedfoldere configure-o para executar na inicialização do computador, por technet.microsoft.com/en-us/library/cc770556.aspx Isso será executado como a conta SYSTEM, portanto, não é necessário psexec.
TRS-80
2
Quero acrescentar que é importante que todos usem a cláusula /USER:[remotecomp]\[remoteusername] [password](o comando às vezes não funciona corretamente quando o nome de usuário remoto não é precedido por um nome de computador remoto e uma barra invertida. Além disso, se o compartilhamento estiver protegido por senha e aparecer para outros como desconectado conduzir, é não acessível para todos Qualquer usuário no sistema, onde o sistema monta uma parte deve saber a senha para que a participação (testado em XPx64)..
Kitet
65

Encontrei uma solução semelhante à do psexec, mas funciona sem ferramentas adicionais e sobrevive a uma reinicialização .

Apenas adicione uma tarefa programada, insira "system" no campo "run as" e aponte a tarefa para um arquivo em lotes com o comando simples

net use z: \servername\sharedfolder /persistent:yes

Em seguida, selecione "executar na inicialização do sistema" (ou similar, eu não tenho uma versão em inglês) e pronto.

Larry
fonte
o que começa primeiro? um serviço do Windows ou esta tarefa agendada? nosso serviço morre no início se o caminho estiver indisponível. Teríamos que reconstruir isso se o serviço iniciar por último.
Thomas
1
Eu tentei isso no 2008 R2, ele cria uma unidade mapeada desconectada e, quando tento abrir o mesmo, diz "z: \ não está acessível. Falha no logon: nome de usuário desconhecido ou senha incorreta". Mas consegui criar a unidade mapeada com êxito executando o mesmo arquivo bat manualmente. Ny insights?
Gopi
1
@Thomas não importa que começa primeiro proporcionando a tarefa foi executada pelo menos uma vez por causa do/persistent:yes
Edd
4
Por que precisa ser uma tarefa agendada? É / persistente: sim, não é suficiente para mantê-lo por perto?
Scott Stafford
2
@ ScottStafford Não / persistente: sim, não é suficiente no Win7 e posterior. O mapeamento é removido após a reinicialização, independentemente dessa opção.
Eternal21
44

Uma maneira melhor seria usar um link simbólico usando o mklink.exe. Você pode apenas criar um link no sistema de arquivos que qualquer aplicativo possa usar. Veja http://en.wikipedia.org/wiki/NTFS_symbolic_link .

Hal
fonte
Tão simples e funciona bem. Como faz parte do sistema de arquivos, o link está disponível para todas as contas. Apenas verifique se o serviço está sendo executado como uma conta que tenha acesso ao recurso de rede (que pode não ser o caso do sistema etc.).
Jeremy Frank
1
Esta é definitivamente a melhor resposta para a pergunta, muito obrigado!
precisa
3
Infelizmente, se o link sym acessa um compartilhamento de rede, então você está de volta para um quadrado
davidfrancis
23

Há uma boa resposta aqui: https://superuser.com/a/651015/299678

Ou seja, você pode usar um link simbólico, por exemplo

mklink /D C:\myLink \\127.0.0.1\c$
philu
fonte
1
E se você tentar criar um diretório dentro do serviço com um erro de permissão?
amigos estão dizendo sobre tyc213
Você deve colocá-lo off-line em uma sala de bate-papo e fornecer detalhes da mensagem de erro. Você provavelmente precisará executar os comandos com permissões elevadas.
precisa saber é
@ tyoc213 Você recebeu uma resposta?
Lsakurifaisu 25/07/19
9

Você pode nos usar o comando 'net use':

var p = System.Diagnostics.Process.Start("net.exe", "use K: \\\\Server\\path");
var isCompleted = p.WaitForExit(5000);

Se isso não funcionar em um serviço, tente o Winapi e o PInvoke WNetAddConnection2

Edit: Obviamente eu te entendi mal - você não pode alterar o código-fonte do serviço, certo? Nesse caso, eu seguiria a sugestão do mdb , mas com uma pequena reviravolta: crie seu próprio serviço (vamos chamá-lo de serviço de mapeamento) que mapeia a unidade e adicione esse serviço de mapeamento às dependências do primeiro (o trabalho real). Dessa forma, o serviço em funcionamento não será iniciado antes que o serviço de mapeamento tenha sido iniciado (e mapeado a unidade).

Treb
fonte
com essa configuração do serviço de mapeamento, acho que o mapeamento de unidade estabelecido pelo serviço de mapeamento não estaria disponível no contexto do serviço original, estaria?
VoidPointer 10/10/08
Eu acho que <disclaim> deveria </disclaim> - há apenas um ambiente para cada sessão do winlogon.
10238 Treb
Seu código funciona em um serviço. Eu vim aqui com o mesmo problema que o OP, mas sou o autor do Serviço. Sua resposta resolveu meu problema.
Joe Gayetty 6/03/2017
5

ForcePush,

NOTA : A unidade mapeada recém-criada agora será exibida para TODOS os usuários deste sistema, mas será exibida como "Unidade de rede desconectada (Z :)". Não deixe o nome enganar você. Pode alegar estar desconectado, mas funcionará para todos. É assim que você pode dizer que esse hack não é suportado por M $ ...

Tudo depende das permissões de compartilhamento. Se você tiver todos nas permissões de compartilhamento, esta unidade mapeada poderá ser acessada por outros usuários. Mas se você tiver apenas um usuário em particular cujas credenciais você usou em seu script em lote e esse script em lote foi adicionado aos scripts de Inicialização, apenas a conta do Sistema terá acesso a esse compartilhamento, nem mesmo ao Administrador. Portanto, se você usar, por exemplo, um trabalho ntbackuo agendado, a conta do sistema deverá ser usada em 'Executar como'. Se o serviço 'Efetuar logon como: conta do sistema local' deve funcionar.

O que fiz , não mapeei nenhuma letra de unidade no meu script de inicialização, apenas usei net use \\\server\share ...e usei o caminho UNC nos meus trabalhos agendados. Adicionado um script de logon (ou apenas adicione um arquivo em lotes à pasta de inicialização) com o mapeamento para o mesmo compartilhamento com alguma letra de unidade: net use Z: \\\...com as mesmas credenciais. Agora, o usuário conectado pode ver e acessar a unidade mapeada. Existem 2 conexões para o mesmo compartilhamento. Nesse caso, o usuário não vê a irritante "Unidade de rede desconectada ...". Porém, se você realmente precisar acessar esse compartilhamento pela letra da unidade e não apenas pelo UNC, mapeie esse compartilhamento com as diferentes letras da unidade, por exemplo, Y para System e Z para usuários.

lk7777
fonte
4

Foi encontrada uma maneira de conceder acesso ao Serviço Windows à Unidade de Rede.

Veja o Windows Server 2012 com disco NFS, por exemplo:

Etapa 1: escreva um arquivo em lotes para montar.

Escreva um arquivo em lotes, por exemplo: C: \ mount_nfs.bat

echo %time% >> c:\mount_nfs_log.txt
net use Z: \\{your ip}\{netdisk folder}\ >> C:\mount_nfs_log.txt 2>&1

Etapa 2: Monte o disco como NT AUTHORITY / SYSTEM.

Abra "Agendador de tarefas", crie uma nova tarefa:

  1. Execute como "SYSTEM", em "System Startup".
  2. Criar ação: Execute "C: \ mount_nfs.bat".

Após essas duas etapas simples, meu serviço Windows ActiveMQ, executado na privilégio "Sistema local", executa perfeitamente sem login.

Val
fonte
3

O motivo pelo qual você pode acessar a unidade quando normalmente executa o executável no prompt de comando é que, quando você o executa como exe normal, você está executando esse aplicativo na conta de Usuário na qual efetuou logon. E esse usuário tem privilégios para acessar a rede. Mas, quando você instala o executável como um serviço, por padrão, se você vê na tarefa gerenciar, ele é executado na conta 'SISTEMA'. E você pode estar sabendo que o 'SISTEMA' não tem direitos para acessar os recursos da rede.

Pode haver duas soluções para esse problema.

  1. Para mapear a unidade como persistente, como já indicado acima.

  2. Há mais uma abordagem que pode ser seguida. Se você abrir o gerenciador de serviços, digitando 'services.msc', poderá acessar o serviço e, nas propriedades do serviço, há uma guia de logon em que é possível especificar a conta como qualquer outra conta que não seja 'System'. inicie o serviço usando sua própria conta de usuário conectada ou através do 'Serviço de Rede'. Quando você faz isso .. o serviço pode acessar qualquer componente de rede e unidade, mesmo que eles também não sejam persistentes. Para conseguir isso programaticamente, você pode procurar a função 'CreateService' em http://msdn.microsoft.com/en-us/library/ms682450(v=vs.85).aspx e pode definir o parâmetro 'lpServiceStartName' como 'NT AUTHORITY \ NetworkService '. Isso iniciará seu serviço em 'Serviço de Rede'

  3. Você também pode tentar tornar o serviço interativo, especificando SERVICE_INTERACTIVE_PROCESS no sinalizador de parâmetro servicetype da sua função CreateService (), mas isso será limitado apenas até XP, pois o Vista e o 7 não suportam esse recurso.

Espero que as soluções o ajudem. Deixe-me saber se isso funcionou para você.

Kushagra
fonte
1

Você não deve alterar o usuário sob o qual o Serviço executa em "Sistema" ou encontrar uma maneira sorrateira de executar seu mapeamento como Sistema.

O engraçado é que isso é possível usando o comando "at" , basta agendar seu mapeamento de unidade em um minuto no futuro e ele será executado na conta Sistema, tornando a unidade visível para o seu serviço.

Torbjörn Gyllebring
fonte
o serviço não é executado como "Sistema". Ele está configurado para ser executado em uma conta local específica. Mesmo que eu faça login com essa conta, crie um mapeamento de rede persistente, efetue logout e reinicie o serviço, o mapeamento não estará disponível para o serviço.
VoidPointer 8/10/08
1

Em vez de depender de uma unidade persistente, você pode definir o script para mapear / remover o mapeamento da unidade cada vez que a usar:

net use Q: \\share.domain.com\share 
forfiles /p Q:\myfolder /s /m *.txt /d -0 /c "cmd /c del @path"
net use Q: /delete

Isso funciona para mim.

jeff
fonte
0

Ainda não posso comentar (trabalhando em reputação), mas criei uma conta apenas para responder aos problemas de @Tech Jerk @ spankmaster79 (bom nome lol) e @NMC que eles relataram em resposta à mensagem "Encontrei uma solução semelhante à psexec, mas funciona sem ferramentas adicionais e sobrevive a uma reinicialização. " post @Larry tinha feito.

A solução para isso é simplesmente navegar para essa pasta na conta conectada, ou seja:

    \\servername\share  

e solicite o login, e insira as mesmas credenciais usadas para o UNC no psexec. Depois disso, começa a funcionar. No meu caso, acho que isso ocorre porque o servidor com o serviço não é membro do mesmo domínio que o servidor para o qual estou mapeando. Estou pensando se o UNC e a tarefa agendada se referem ao IP em vez de hostname

    \\123.456.789.012\share 

isso pode evitar o problema completamente.

Se algum dia eu receber pontos suficientes aqui, adicionarei isso como resposta.

CanadaDave
fonte