Atribuindo permissões NTFS com C# e PowerShell

Atribuir permissões NTFS com DirectoryEntry é demorado e sujeito à falhas. Uma alternativa fazê-lo com Cmdlets do PowerShell para manusear a Access Control List (ACL), mais especificamente Set-ACL e Get-ACL Primeiramente vamos aos comandos necessários em PowerShell.

# retornar lista de controle de acesso de um diretório
$acl = Get-Acl c:\temp

# variavel que armazena a permissão a ser concedida
$permission = "meudominio\usuarioficticio","FullControl","Allow"

# setando a nova regra para o diretório
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($accessRule)
$acl | Set-Acl c:\temp

O segundo passo é executar o comando acima em C#. Segue o código:

//utilizar a sobrecarga que melhor atender sua necessidade
var conectionWsMan = new WSManConnectionInfo()
{
AuthenticationMechanism = AuthenticationMechanism.Kerberos,
ProxyAuthentication = AuthenticationMechanism.Negotiate,
};

var ps = PowerShell.Create();
var runspace = RunspaceFactory.CreateRunspace(conectionWsMan);
runspace.Open();
ps.Runspace = runspace;

ps.AddScript("$acl = Get-Acl c:\\temp");
ps.AddScript("$permission = \"meudominio\\usuarioficticio\",\"FullControl\",\"Allow\"");
ps.AddScript("$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission");
ps.AddScript("$acl.SetAccessRule($accessRule)");
ps.AddScript("$acl | Set-Acl c:\\temp");
ps.Invoke();

Abaixo estão as principais permissões que mais frequentemente são configuradas:

  • FullControl
  • Modify
  • ReadAndExecute
  • ListDirectory
  • Read
  • Write

Resolvendo problema com Timer em Windows Service

Um problema que enfrentei há alguns dias foi colocar um Timer que funcionasse dentro de um Windows Service.

Se você tem um cenário onde necessita que um serviço realize uma rotina de tempos em tempos, a primeira solução que nos vem à cabeça é usar um Timer, certo? Certo! Porém quando tu vais até a Toolbox e arrasta um componente Timer para teu serviço, o Visual Studio automaticamente instancia um objeto do tipo System.Threading.Timer.

Qual o problema? Um System.Threading.Timer funciona muito bem em Windows Forms ou Web Forms, mas em Windows Service ele não funciona.

Qual a solução? System.Timers.Timer. Funciona igual ao Timer do namespace Threading, a única diferença é o evento acionado a cada ciclo, ou seja, em vez de service1_Tick, tu terás service1_Elapsed.

Mão na massa

1) Após criar seu projeto WindowsService, vá até até o arquivo Designer do seu serviço (no Solution Explorer, botão direito sobre Service1.cs e depois em View Designer (Shift+F7)).

2) Crie um atributo de classe do tipo System.Timers.Timer e dentro do método InitializeComponents crie uma instância para o mesmo. Delegue também um EventHandler para o evento Elapsed.

3)  Por último, no code-behind do teu serviço, crie o método para o evento Elapsed, com as linhas de código que deseja executar a cada ciclo o Timer. Não esqueça de “startar” o Timer chamando o método _timer.Start(). Sugiro fazer isso no evento OnStart do serviço.

Hello world!

Olá pessoal, o objetivo deste blog é postar toda e qualquer informação que eu julgar útil compartilhar na rede, desde coisas inúteis (porém legais) até aqueles códigos mais tenebrosos que eu demorei dias para desenvolver ou encontrar a solução de um problema que tira o sono de muito programador, assim como eu.

Um pouco sobre mim…
Programador .NET e cuca de ferro em SQL. Desenvolvedor scrum master em projetos ágeis (ainda não certificado, mas a caminho). Gaúcho, 23 anos, gremista e geminiano.

Notou que o blog é feito com WordPress?
É verdade amigos. O foco do blog é .NET, mas o blog é em PHP. Por quê? Porque eu julgo o WordPress mais fácil de usar, bem completo e perfeito para o usuário (eu), já que meu foco é apenas postar informações e não mexer em nenhuma linha de código da ferramenta. Além disso, não sou xiita, que julgo apenas o .NET bom e o resto sendo ruim, apenas tenho preferência por desenvolver em .NET. Abraços!