Mapear una unidad de red para ser utilizada por un servicio

213

Supongamos que algún servicio de Windows usa código que quiere unidades de red mapeadas y no rutas UNC. ¿Cómo puedo hacer que la asignación de unidades esté disponible para la sesión del servicio cuando se inicia el servicio? Iniciar sesión como usuario del servicio y crear una asignación persistente no establecerá la asignación en el contexto del servicio real.

VoidPointer
fuente
66
Vea la respuesta de ForcePush, su solución funciona.
Ubikuity

Respuestas:

44

Deberá modificar el servicio o incluirlo dentro de un proceso auxiliar: además de los problemas de acceso a la sesión / unidad, las asignaciones de unidades persistentes solo se restauran en un inicio de sesión interactivo, que los servicios generalmente no realizan.

El enfoque del proceso auxiliar puede ser bastante simple: simplemente cree un nuevo servicio que mapee el disco e inicie el servicio 'real'. Las únicas cosas que no son del todo triviales sobre esto son:

  • El servicio auxiliar deberá pasar todos los comandos SCM apropiados (inicio / parada, etc.) al servicio real. Si el servicio real acepta comandos SCM personalizados, recuerde pasarlos también (no espero que un servicio que considere que las rutas UNC sean exóticas para usar tales comandos ...)

  • Las cosas pueden ponerse un poco complicadas en cuanto a credenciales. Si el servicio real se ejecuta bajo una cuenta de usuario normal, también puede ejecutar el servicio auxiliar bajo esa cuenta, y todo debería estar bien siempre que la cuenta tenga acceso apropiado al recurso compartido de red. Si el servicio real solo funciona cuando se ejecuta como LOCALSYSTEM o somesuch, las cosas se vuelven más interesantes, ya que no podrá "ver" la unidad de red o requerirá un malabarismo de credenciales para que las cosas funcionen.

mdb
fuente
2
Muy informativo ... ¿Estoy en lo cierto al suponer que los scripts de inicio de sesión también se ejecutan solo para sesiones de inicio de sesión interactivas y no para sesiones de servicio?
VoidPointer
220

Usa esto bajo tu propio riesgo. (Lo he probado en XP y Server 2008 x64 R2)

Para este hack necesitarás SysinternalsSuite de Mark Russinovich :

Paso uno: abra un indicador elevado de cmd.exe (Ejecutar como administrador)

Paso dos: Vuelva a elevarse a la raíz con PSExec.exe: navegue a la carpeta que contiene SysinternalsSuite y ejecute el siguiente comando psexec -i -s cmd.exe que ahora está dentro de un indicador que es nt authority\systemy puede probarlo escribiendo whoami. Se -inecesita porque las asignaciones de unidades deben interactuar con el usuario

Paso tres: cree la unidad asignada persistente como la cuenta SYSTEM con el siguiente comando net use z: \\servername\sharedfolder /persistent:yes

¡Es fácil!

ADVERTENCIA : Solo puede eliminar esta asignación de la misma manera que la creó, de la cuenta SYSTEM. Si necesita eliminarlo, siga los pasos 1 y 2, pero cambie el comando del paso 3 a net use z: /delete.

NOTA : La unidad asignada recién creada ahora aparecerá para TODOS los usuarios de este sistema, pero la verán mostrada como "Unidad de red desconectada (Z :)". No dejes que el nombre te engañe. Puede afirmar que está desconectado, pero funcionará para todos. Así es como se puede decir que este truco no es compatible con M $.

ForcePush
fuente
3
Estaba tratando de usar esta solución y me encontré con este problema: la unidad asignada aparece como desconectada para los usuarios (incluso los administradores). ¿Alguna sugerencia?
Constantin Baciu
77
Después de reiniciar, la unidad asignada desaparece. ¿Alguna idea? El mapeo persiste, pero el estado es "No disponible" por lo que no aparece
Tommy
44
También veo la asignación como no disponible después de un reinicio.
Dave Patterson
33
Para que funcione después de un reinicio, cree un script que solo contenga net use z: \\servername\sharedfoldery configúrelo para que se ejecute en el inicio de la computadora, de acuerdo con technet.microsoft.com/en-us/library/cc770556.aspx Esto se ejecutará como la cuenta del SISTEMA, por lo que no es necesario psexec.
TRS-80
2
Quiero agregar que es importante que todos usen la cláusula /USER:[remotecomp]\[remoteusername] [password](el comando no funciona correctamente a veces cuando el nombre de usuario remoto no está precedido por el nombre de la computadora remota y una barra diagonal inversa. Además, si el recurso compartido está protegido con contraseña y aparece para otros como desconectado) unidad, NO es accesible para todos. Cualquier usuario en ese sistema, donde SYSTEM monta un recurso compartido debe conocer la contraseña de ese recurso compartido (probado en XPx64)
Kitet
65

Encontré una solución que es similar a la de psexec, pero funciona sin herramientas adicionales y sobrevive al reiniciar .

Simplemente agregue una tarea programada, inserte "sistema" en el campo "ejecutar como" y apunte la tarea a un archivo por lotes con el comando simple

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

Luego seleccione "ejecutar al inicio del sistema" (o similar, no tengo una versión en inglés) y ya está.

larry
fuente
¿Qué comienza primero? un servicio de windows o esta tarea programada? nuestro servicio muere al inicio si la ruta no está disponible. Tendríamos que reconstruir esto si el servicio comienza en último lugar.
Thomas
1
Probé esto en 2008 R2, crea una unidad asignada desconectada y cuando intento abrir la misma dice "z: \ no está accesible. Error de inicio de sesión: nombre de usuario desconocido o contraseña incorrecta". Pero pude crear una unidad asignada con éxito ejecutando el mismo archivo bat manualmente. Ny insights?
Gopi
1
@Thomas no importa cuál comience primero, siempre que la tarea se haya ejecutado al menos una vez debido a la/persistent:yes
Edd
44
¿Por qué debe ser una tarea programada? Es / persistente: sí, ¿no es suficiente para mantenerlo?
Scott Stafford
2
@ScottStafford No / persistente: sí no es suficiente en Win7 y versiones posteriores. La asignación se elimina después del reinicio, independientemente de ese cambio.
Eternal21
44

Una mejor manera sería usar un enlace simbólico usando mklink.exe. Simplemente puede crear un enlace en el sistema de archivos que cualquier aplicación pueda usar. Ver http://en.wikipedia.org/wiki/NTFS_symbolic_link .

Hal
fuente
Tan simple y funciona bien. Como es parte del sistema de archivos, el enlace está disponible para todas las cuentas. Solo asegúrese de que el servicio se esté ejecutando como una cuenta que tiene acceso al recurso de red (que podría no ser el caso del Sistema, etc.).
Jeremy Frank
1
Esta es DEFINITIVAMENTE la mejor respuesta a la pregunta, ¡muchas gracias!
Sten Petrov
3
Desafortunadamente, si el enlace sym accede a un recurso compartido de red después de que hayas vuelto a un cuadrado
davidfrancis
23

Aquí hay una buena respuesta: https://superuser.com/a/651015/299678

Es decir, puede usar un enlace simbólico, p. Ej.

mklink /D C:\myLink \\127.0.0.1\c$
philu
fuente
1
¿Qué sucede si después de intentar crear un directorio desde el servicio aparece un error de permiso?
tyoc213
Debe llevar esto fuera de línea a una sala de chat y luego dar detalles del mensaje de error. Probablemente necesite ejecutar los comandos con permisos elevados.
philu
@ tyoc213 ¿Recibiste una respuesta?
Lsakurifaisu
9

Podrías usar el comando 'uso neto':

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

Si eso no funciona en un servicio, pruebe Winapi y PInvoke WNetAddConnection2

Editar: Obviamente te entendí mal, no puedes cambiar el código fuente del servicio, ¿verdad? En ese caso, seguiría la sugerencia de mdb , pero con un pequeño giro: cree su propio servicio (llamémoslo servicio de mapeo) que mapea el disco y agregue este servicio de mapeo a las dependencias para el primer servicio (el trabajo real). De esa manera, el servicio de trabajo no se iniciará antes de que el servicio de mapeo haya comenzado (y haya mapeado la unidad).

Treb
fuente
con esta configuración del servicio de mapeo, creo que la asignación de unidades establecida por el servicio de mapeo no estaría disponible en el contexto del servicio original, ¿verdad?
VoidPointer
Creo que <disclaim> debería </disclaim>: solo hay un entorno para cada sesión de winlogon.
Treb
Su código sí funciona en un servicio. Vine aquí con el mismo problema que el OP pero soy el autor del Servicio. Tu respuesta resolvió mi problema.
Joe Gayetty
5

ForcePush,

NOTA : La unidad asignada recién creada ahora aparecerá para TODOS los usuarios de este sistema, pero la verán mostrada como "Unidad de red desconectada (Z :)". No dejes que el nombre te engañe. Puede afirmar que está desconectado, pero funcionará para todos. Así es como se puede decir que este truco no es compatible con M $ ...

Todo depende de los permisos compartidos. Si tiene todos los permisos para compartir, otros usuarios podrán acceder a esta unidad asignada. Pero si solo tiene un usuario en particular cuyas credenciales utilizó en su secuencia de comandos por lotes y esta secuencia de comandos por lotes se agregó a las secuencias de comandos de inicio, solo la cuenta del sistema tendrá acceso a ese recurso compartido, ni siquiera el administrador. Entonces, si usa, por ejemplo, un trabajo ntbackuo programado, la cuenta del sistema debe usarse en 'Ejecutar como'. Si su servicio 'Iniciar sesión como: cuenta del sistema local' debería funcionar.

Lo que hice , no asigné ninguna letra de unidad en mi script de inicio, solo usé net use \\\server\share ...y usé la ruta UNC en mis trabajos programados. Se agregó un script de inicio de sesión (o simplemente agregue un archivo por lotes a la carpeta de inicio) con la asignación al mismo recurso compartido con alguna letra de unidad: net use Z: \\\...con las mismas credenciales. Ahora el usuario registrado puede ver y acceder a esa unidad asignada. Hay 2 conexiones al mismo recurso compartido. En este caso, el usuario no ve esa molesta "Unidad de red desconectada ...". Pero si realmente necesita acceso a ese recurso compartido por la letra de unidad, no solo UNC, asigne ese recurso compartido con las diferentes letras de unidad, por ejemplo, Y para Sistema y Z para usuarios.

lk7777
fuente
4

Se encontró una forma de otorgar acceso al Servicio de Windows a la Unidad de red.

Tome Windows Server 2012 con disco NFS por ejemplo:

Paso 1: escriba un archivo por lotes para montar.

Escriba un archivo por lotes, por ejemplo: 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

Paso 2: Monte el disco como NT AUTHORITY / SYSTEM.

Abra el "Programador de tareas", cree una nueva tarea:

  1. Ejecutar como "SISTEMA", en "Inicio del sistema".
  2. Crear acción: Ejecute "C: \ mount_nfs.bat".

Después de estos dos simples pasos, mi servicio Windows ActiveMQ se ejecuta bajo el privilegio "Sistema local", funciona perfectamente sin iniciar sesión.

Val
fuente
3

La razón por la que puede acceder al disco cuando normalmente ejecuta el ejecutable desde el símbolo del sistema es que cuando lo está ejecutando como exe normal, está ejecutando esa aplicación en la cuenta de usuario desde la que ha iniciado sesión. Y ese usuario tiene los privilegios para acceder a la red. Pero, cuando instala el ejecutable como un servicio, de forma predeterminada, si ve en la gestión de tareas, se ejecuta en la cuenta 'SISTEMA'. Y es posible que sepa que el 'SISTEMA' no tiene derechos para acceder a los recursos de la red.

Puede haber dos soluciones a este problema.

  1. Para mapear el disco tan persistente como ya se señaló anteriormente.

  2. Hay un enfoque más que se puede seguir. Si abre el administrador de servicios escribiendo 'services.msc', puede ir a su servicio y en las propiedades de su servicio hay una pestaña de inicio de sesión donde puede especificar la cuenta como cualquier otra cuenta que no sea 'Sistema'. inicie el servicio desde su propia cuenta de usuario conectada o mediante 'Servicio de red'. Cuando hace esto ... el servicio puede acceder a cualquier componente de red y unidad, incluso si no son persistentes también. Para lograr esto mediante programación, puede buscar en la función 'CreateService' en http://msdn.microsoft.com/en-us/library/ms682450(v=vs.85).aspx y puede establecer el parámetro 'lpServiceStartName' en 'NT AUTORIDAD \ NetworkService '. Esto iniciará su servicio en 'Servicio de red'

  3. También puede intentar hacer que el servicio sea interactivo especificando SERVICE_INTERACTIVE_PROCESS en el indicador de parámetro de tipo de servicio de su función CreateService (), pero esto se limitará solo hasta XP, ya que Vista y 7 no admiten esta función.

Espero que las soluciones te ayuden. Avísame si esto funcionó para ti.

Kushagra
fuente
1

No desea cambiar el usuario con el que se ejecuta el Servicio desde "Sistema" o encontrar una manera astuta de ejecutar su mapeo como Sistema.

Lo curioso es que esto es posible mediante el uso del comando "at" , simplemente programe su asignación de unidades un minuto en el futuro y se ejecutará en la cuenta del sistema, haciendo que la unidad sea visible para su servicio.

Torbjörn Gyllebring
fuente
el servicio no se ejecuta como "Sistema". Está configurado para ejecutarse bajo una cuenta local específica. Incluso al iniciar sesión con esa cuenta, crear una asignación de red persistente, cerrar sesión y reiniciar el servicio, la asignación no estará disponible para el servicio.
VoidPointer
1

En lugar de confiar en una unidad persistente, puede configurar el script para asignar / desasignar la unidad cada vez que la use:

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

Esto funciona para mi.

jeff
fuente
0

Todavía no puedo comentar (trabajando en reputación), pero creé una cuenta solo para responder a @Tech Jerk @ spankmaster79 (bonito nombre jajaja) y a los problemas de @NMC que informaron en respuesta al "Encontré una solución similar a la que tenía psexec pero funciona sin herramientas adicionales y sobrevive al reiniciar ". la publicación que @Larry había hecho.

La solución a esto es simplemente navegar a esa carpeta desde la cuenta registrada, es decir:

    \\servername\share  

y deje que le solicite iniciar sesión e ingrese las mismas credenciales que utilizó para la UNC en psexec. Después de eso comienza a funcionar. En mi caso, creo que esto se debe a que el servidor con el servicio no es miembro del mismo dominio que el servidor al que estoy asignando. Estoy pensando si la UNC y la tarea programada se refieren a la IP en lugar del nombre de host

    \\123.456.789.012\share 

Puede evitar el problema por completo.

Si alguna vez obtengo suficientes puntos de representación aquí, agregaré esto como respuesta.

CanadáDave
fuente