Mappare un’unità di rete per essere utilizzata da un servizio

Supponiamo che alcuni servizi di Windows utilizzino un codice che richiede unità di rete mappate e nessun percorso UNC. Come posso rendere disponibile la mapping dell’unità alla sessione del servizio all’avvio del servizio? L’accesso come utente del servizio e la creazione di una mapping persistente non stabiliscono la mapping nel contesto del servizio effettivo.

È necessario modificare il servizio o inserirlo in un processo di supporto: oltre ai problemi di accesso alla sessione / unità, i mapping di unità permanenti vengono ripristinati solo su un accesso interattivo, che in genere i servizi non eseguono.

L’approccio al processo di supporto può essere piuttosto semplice: basta creare un nuovo servizio che mappa l’unità e avvia il servizio ‘reale’. Le uniche cose che non sono del tutto banali su questo sono:

  • Il servizio di supporto dovrà trasmettere tutti i comandi SCM appropriati (avvio / arresto, ecc.) Al servizio reale. Se il servizio reale accetta comandi SCM personalizzati, ricordati di inoltrarli (non mi aspetto un servizio che consideri i percorsi UNC esotici utilizzare tali comandi, sebbene …)

  • Le cose potrebbero diventare un po ‘complicate in termini di credenziali. Se il servizio reale viene eseguito con un account utente normale, è ansible eseguire anche il servizio di supporto con tale account, e tutto dovrebbe essere corretto purché l’account disponga di un accesso appropriato alla condivisione di rete. Se il vero servizio funzionerà solo quando viene eseguito come LOCALSYSTEM o somesuch, le cose diventano più interessanti, in quanto non sarà in grado di “vedere” il disco di rete o richiedere qualche giocoleria di credenziali per far funzionare le cose.

Usalo a tuo rischio e pericolo. (L’ho provato su XP e Server 2008 x64 R2)

Per questo hack è necessario SysinternalsSuite di Mark Russinovich :

Fase 1: aprire un prompt cmd.exe con privilegi elevati (Esegui come amministratore)

Passo 2: rialzare nuovamente per eseguire il root utilizzando PSExec.exe: accedere alla cartella contenente SysinternalsSuite ed eseguire il seguente comando psexec -i -s cmd.exe si trova ora all’interno di un prompt che è nt authority\system e si può provare con digitando whoami . Il -i è necessario perché i mapping di unità devono interagire con l’utente

Passaggio 3: Creare l’unità mappata permanente come account SYSTEM con il seguente comando net use z: \\servername\sharedfolder /persistent:yes

È così facile!

ATTENZIONE : puoi rimuovere questa mapping nello stesso modo in cui l’hai creata, dall’account SYSTEM. Se è necessario rimuoverlo, seguire i passaggi 1 e 2, ma modificare il comando nel passaggio 3 in net use z: /delete .

NOTA : l’unità mappata appena creata verrà ora visualizzata per TUTTI gli utenti di questo sistema, ma verrà visualizzata come “Unità di rete disconnessa (Z :)”. Non farti ingannare dal nome. Potrebbe richiedere di essere disconnesso ma funzionerà per tutti. Ecco come puoi dire che questo hack non è supportato da M $.

Ho trovato una soluzione simile a quella con psexec ma funziona senza strumenti aggiuntivi e sopravvive a un riavvio .

Basta aggiungere un’attività pianificata, inserire “sistema” nel campo “Esegui come” e indirizzare l’attività a un file batch con il comando semplice

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

Quindi selezionare “Esegui all’avvio del sistema” (o simile, non ho una versione inglese) e il gioco è fatto.

Un modo migliore sarebbe utilizzare un collegamento simbolico usando mklink.exe. Puoi semplicemente creare un collegamento nel file system che qualsiasi app può utilizzare. Vedi http://en.wikipedia.org/wiki/NTFS_symbolic_link .

Potresti usare il comando ‘net use’:

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

Se ciò non funziona in un servizio, prova Winapi e PInvoke WNetAddConnection2

Edit: Ovviamente ho frainteso te – non è ansible modificare il codice sorgente del servizio, giusto? In questo caso seguirò il suggerimento di MDB , ma con una piccola svolta: crea il tuo servizio (chiamiamolo servizio di mapping) che mappa l’unità e aggiungi questo servizio di mapping alle dipendenze per il primo servizio (il lavoro effettivo). In questo modo il servizio di lavoro non verrà avviato prima dell’avvio del servizio di mapping (e mappato l’unità).

C’è una buona risposta qui: https://superuser.com/a/651015/299678

Ad esempio, è ansible utilizzare un collegamento simbolico, ad es

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

ForcePush,

NOTA : l’unità mappata appena creata verrà ora visualizzata per TUTTI gli utenti di questo sistema, ma verrà visualizzata come “Unità di rete disconnessa (Z :)”. Non farti ingannare dal nome. Potrebbe richiedere di essere disconnesso ma funzionerà per tutti. Ecco come puoi dire che questo hack non è supportato da M $ …

Tutto dipende dalle autorizzazioni di condivisione. Se si dispone di Everyone nelle autorizzazioni di condivisione, questa unità mappata sarà accessibile da altri utenti. Ma se si ha solo un utente particolare con le credenziali utilizzate nello script batch e questo script batch è stato aggiunto agli script di avvio, solo l’account di sistema avrà accesso a tale condivisione, nemmeno l’amministratore. Pertanto, se si utilizza, ad esempio, un processo ntbackuo pianificato, è necessario utilizzare l’account di sistema in “Esegui come”. Se il tuo servizio ‘Accedi come: account di sistema locale’ dovrebbe funzionare.

Quello che ho fatto , non ho mappato nessuna lettera di unità nel mio script di avvio, ho solo usato net use \\\server\share ... e ho usato il percorso UNC nei miei lavori programmati. Aggiunto uno script di accesso (o semplicemente aggiungere un file batch alla cartella di avvio) con il mapping alla stessa condivisione con qualche lettera di unità: net use Z: \\\... con le stesse credenziali. Ora l’utente registrato può vedere e accedere a quell’unità mappata. Ci sono 2 connessioni per la stessa condivisione. In questo caso l’utente non vede quella fastidiosa “Unità di rete disconnessa …”. Ma se hai davvero bisogno di accedere a quella condivisione con la lettera di unità non solo UNC, mappare quella condivisione con le diverse lettere di unità, ad es. Y per Sistema e Z per gli utenti.

Trovato un modo per concedere l’accesso al servizio di Windows a Network Drive.

Ad esempio, prendi Windows Server 2012 con NFS Disk:

Passaggio 1: scrivere un file batch da montare.

Scrivi un file batch, es: 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 

Passaggio 2: Monta il disco come NT AUTHORITY / SYSTEM.

Aprire “Task Scheduler”, creare una nuova attività:

  1. Esegui come “SYSTEM”, in “Avvio del sistema”.
  2. Crea azione: esegui “C: \ mount_nfs.bat”.

Dopo questi due semplici passaggi, il mio servizio Windows ActiveMQ eseguito in privilegio “Sistema locale”, si comporta perfettamente senza effettuare il login.

Il motivo per cui si è in grado di accedere all’unità quando normalmente si esegue il file eseguibile dal prompt dei comandi è che quando lo si esegue come exe normale si sta eseguendo quell’applicazione nell’account Utente dal quale è stato effettuato l’accesso. E quell’utente ha i privilegi per accedere alla rete. Tuttavia, quando si installa l’eseguibile come servizio, per impostazione predefinita se viene visualizzato nell’attività gestita, viene eseguito con l’account ‘SISTEMA’. E potresti sapere che il ‘SISTEMA’ non ha i diritti per accedere alle risorse di rete.

Ci possono essere due soluzioni a questo problema.

  1. Per mappare l’unità come persistente come già indicato sopra.

  2. C’è un altro approccio che può essere seguito. Se apri il gestore servizi digitando ‘services.msc’ puoi andare al tuo servizio e nelle proprietà del tuo servizio c’è una scheda logOn dove puoi specificare l’account come qualsiasi altro account rispetto a ‘Sistema’ puoi avviare il servizio dal proprio account utente connesso o tramite “Servizio di rete”. Quando si esegue questa operazione, il servizio può accedere a qualsiasi componente di rete e guidare anche se non sono persistenti. Per ottenere ciò a livello di programmazione, è ansible esaminare la funzione ‘CreateService’ all’indirizzo http://msdn.microsoft.com/en-us/library/ms682450(v=vs.85).aspx e impostare il parametro ‘lpServiceStartName’ su ‘NT AUTHORITY \ NetworkService’. Questo avvierà il tuo servizio sotto l’account ‘Servizio di rete’ e poi hai finito.

  3. Puoi anche provare rendendo il servizio interattivo specificando SERVICE_INTERACTIVE_PROCESS nel flag parametro servicetype della tua funzione CreateService (), ma questo sarà limitato solo fino a XP come Vista e 7 non supportano questa funzionalità.

Spero che le soluzioni ti aiutino .. Fammi sapere se questo ha funzionato per te.

Non è necessario modificare l’utente in cui viene eseguito il servizio da “Sistema” o trovare un modo subdolo per eseguire il mapping come Sistema.

La cosa divertente è che ciò è ansible usando il comando “at” , semplicemente pianificando la mapping dell’unità nel giro di un minuto e verrà eseguito sotto l’account di sistema, rendendo l’unità visibile al tuo servizio.

Non posso ancora commentare (lavorando sulla reputazione) ma ho creato un account solo per rispondere alle domande @Tech Jerk @ spankmaster79 (bel nome lol) e @NMC che hanno segnalato in risposta al “Ho trovato una soluzione simile a quella con psexec ma funziona senza strumenti aggiuntivi e sopravvive a un riavvio. ” post @Larry aveva fatto.

La soluzione a questo è semplicemente navigare in quella cartella dall’account loggato, cioè:

  \\servername\share 

e lascia che ti chieda di accedere e inserisci le stesse credenziali che hai usato per UNC in Psexec. Dopo di ciò inizia a funzionare. Nel mio caso, penso che questo sia dovuto al fatto che il server con il servizio non è un membro dello stesso dominio del server su cui sto mappando. Sto pensando se l’UNC e l’operazione pianificata si riferiscono entrambi all’IP invece del nome host

  \\123.456.789.012\share 

può evitare del tutto il problema.

Se mai avrò abbastanza punti Rep qui, aggiungerò questo come risposta.

Invece di fare affidamento su un’unità persistente, puoi impostare lo script per mappare / rimuovere l’unità ogni volta che la usi:

 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 

Questo funziona per me.