Asignar una unidad de red para ser utilizada por un servicio

Supongamos que algunos servicios de Windows usan código que quiere unidades de red mapeadas y sin 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 el usuario del servicio y crear una asignación persistente no establecerá la asignación en el contexto del servicio real.

Deberá modificar el servicio o envolverlo dentro de un proceso de ayuda: aparte 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 normalmente no funcionan.

El enfoque del proceso de ayuda puede ser bastante simple: simplemente cree un nuevo servicio que mapee la unidad e inicie el servicio “real”. Las únicas cosas que no son completamente triviales acerca de esto son:

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

  • Las cosas pueden ser un poco engañosas 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 debe 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 algo así, las cosas se vuelven más interesantes, ya que no será capaz de ‘ver’ la unidad de red en absoluto, o requerirá algunos malabarismos de credenciales para hacer que las cosas funcionen.

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

Para este truco necesitarás SysinternalsSuite por Mark Russinovich :

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

Paso dos: eleve nuevamente a la raíz con PSExec.exe: navegue a la carpeta que contiene SysinternalsSuite y ejecute el siguiente comando psexec -i -s cmd.exe . Ahora se encuentra dentro de un indicador que es nt authority\system y puede probar esto mediante escribiendo whoami . El -i es necesario porque las asignaciones de unidad necesitan 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 forma que la creó, desde la cuenta de SYSTEM. Si necesita eliminarlo, siga los pasos 1 y 2, pero cambie el comando en el paso 3 para net use z: /delete .

NOTA : La unidad asignada recientemente creada ahora aparecerá para TODOS los usuarios de este sistema, pero la verán 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 puedes ver que este pirateo no es compatible con M $.

Encontré una solución similar a la de psexec pero funciona sin herramientas adicionales y sobrevive a un reinicio .

Simplemente agregue una tarea proyectada, inserte “sistema” en el campo “ejecutar como” y señale la tarea a un archivo de proceso por lotes con el comando simple

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

Luego seleccione “ejecutar en el inicio del sistema” (o similar, no tengo una versión en inglés) y habrá terminado.

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

Puede usar el comando ‘net use’:

 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 malentendí: 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: crea tu propio servicio (llamémoslo servicio de mapeo) que mapea la unidad y agrega este servicio de mapeo a las dependencias para el primer servicio (el trabajo real). De esta forma, el servicio que funciona no se iniciará antes de que el servicio de mapas haya comenzado (y haya mapeado el disco).

Hay una buena respuesta aquí: https://superuser.com/a/651015/299678

Es decir, puede usar un enlace simbólico, por ejemplo

 mklink /DC:\myLink \\127.0.0.1\c$ 

ForcePush,

NOTA : La unidad asignada recientemente creada ahora aparecerá para TODOS los usuarios de este sistema, pero la verán 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 puedes ver que este pirateo no es compatible con M $ …

Todo depende de los permisos compartidos. Si tiene Todos en los permisos para compartir, otros usuarios podrán acceder a esta unidad asignada. Pero si solo tiene un usuario en particular cuyas credenciales usó 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 esa acción ni siquiera al administrador. Por lo tanto, si utiliza, por ejemplo, un trabajo ntbackuo progtwigdo, la cuenta del sistema debe usarse en ‘Ejecutar como’. Si su servicio es ‘Iniciar sesión como: cuenta del sistema local’ debería funcionar.

Lo que hice , no localicé ninguna letra de unidad en mi secuencia de comandos de inicio, solo utilicé net use \\\server\share ... y usé la ruta UNC en mis trabajos progtwigdos. Se agregó una secuencia de comandos de inicio de sesión (o simplemente agregar un archivo por lotes a la carpeta de inicio) con la asignación al mismo net use Z: \\\... compartido con una letra de unidad: net use Z: \\\... con las mismas credenciales. Ahora el usuario registrado puede ver y acceder a esa unidad mapeada. Hay 2 conexiones para el mismo recurso compartido. En este caso, el usuario no ve esa molesta “Unidad de red desconectada …”. Pero si realmente necesita acceder a ese recurso compartido mediante la letra de la unidad, no solo UNC, haga un mapa que comparta con las diferentes letras de unidad, por ejemplo, Y para System y Z para los usuarios.

Encontré una forma de otorgarle acceso al servicio de Windows a la unidad de red.

Tome Windows Server 2012 con el disco NFS, por ejemplo:

Paso 1: Escribe 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 “Progtwigdor 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 sencillos pasos, mi servicio Windows ActiveMQ se ejecuta bajo el privilegio de “Sistema local” y funciona perfectamente sin iniciar sesión.

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 un exe normal está ejecutando esa aplicación en la cuenta de usuario desde la que inició 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 administració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 asignar 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 al escribir en ‘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 registrada o a través de ‘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 programáticamente, 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 la cuenta ‘Servicio de red’ y luego habrá terminado.

  3. También puede probar haciendo 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 estará limitado solo hasta que XP como Vista y 7 no admitan esta característica.

Espero que las soluciones te ayuden. Hazme saber si esto funcionó para ti.

Desea cambiar el usuario bajo el que funciona el Servicio desde “Sistema” o buscar una forma astuta para ejecutar su asignación como Sistema.

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

No puedo comentar aún (trabajando en reputación) pero creé una cuenta solo para responder a @Tech Jerk @ spankmaster79 (nice name lol) y @NMC que informaron en respuesta al “Encontré una solución que es similar a la de psexec pero funciona sin herramientas adicionales y sobrevive a un reinicio “. publicar 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 se 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 mapeando. Estoy pensando si el UNC y la tarea progtwigda 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 reputación aquí, lo agregaré como respuesta.

En lugar de confiar en un disco persistente, puede configurar el script para asignar / desasignar el disco cada vez que lo 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 mí