16 de nov. de 2011

FTP + Powershell

Bem, como já relatado em outros posts, é possível utilizar classes do .NET Framework no Powershell. Com isso em mente, podemos utilizar uma simples requisição com um WebRequest para estabelecer conexão com um servidor FTP.

Vejamos esse exemplo de como copiar um diretório (seus arquivos e subpastas) para um servidor FTP (mantendo a mesma estrutura).

function DoLogFTP($tamanhoBytes, $fullName)
{
    if($tamanhoBytes -eq $null)
    {
        return;
    }

    $tamanho = $tamanhoBytes/1024;
    $unidade = "KB";
   
    if($tamanho -ge 1024.0)
    {
        $tamanho = $tamanho/1024;
        $unidade = "MB";
    }
   
    $mensagem = [string]::Format("FTP: copiando ({0:0.00} {1}) '{2}' ... ", $tamanho, $unidade, $fullName);

    Write-Host $mensagem;
}

function InstanciarFTPClient([string] $enderecoFTP, [string] $ftpUser, [string] $ftpPassword)
{
    $ftp = [System.Net.WebRequest]::Create($enderecoFTP);               
    $ftp.Credentials = New-Object System.Net.NetworkCredential($ftpUser, $ftpPassword);
   
    return $ftp;
}

function CriarDiretorioFTP([string] $enderecoFTP, [string] $ftpUser, [string] $ftpPassword, [string] $nomeDoDiretorio)
{
    $ftp = InstanciarFTPClient ($enderecoFTP+$nomeDoDiretorio) $ftpUser $ftpPassword;
    $ftp.Method = [System.Net.WebRequestMethods+FTP]::MakeDirectory;               
    $ftp.GetResponse();
}

function EnviarDiretorioViaFTP([string] $diretorioOrigem, [string] $enderecoFTP, [string] $ftpUser, [string] $ftpPassword)
{
    # -> Define um nome do diretório que será criado no servidor FTP.
    $nomeDoDiretorio = $diretorioOrigem.Substring($diretorioOrigem.LastIndexOf('\') + 1, $diretorioOrigem.Length - $diretorioOrigem.LastIndexOf('\') - 1) #(Get-Item $diretorioOrigem).Name; #(New-Object System.IO.DirectoryInfo $diretorioOrigem).Name;
    $nomeDoDiretorio += (Get-Date).ToString(" - dd-MM-yyyy - HH-mm-ss");
    $global:diretorioCriadoNoServidor = $nomeDoDiretorio;
   
    CriarDiretorioFTP $enderecoFTP $ftpUser $ftpPassword $nomeDoDiretorio;

    $diretorioFTP += $enderecoFTP + $nomeDoDiretorio + "/";
    $itensDoDiretorio = Get-ChildItem $diretorioOrigem -recurse;

    foreach($item in $itensDoDiretorio)
    {
        $nomeItem = [System.IO.Path]::GetFullPath($item.FullName).SubString($diretorioOrigem.Length + 1);
       
        DoLogFTP $item.Length $item.FullName;
       
            if ($item.Attributes -eq "Directory")
            {
            CriarDiretorioFTP $diretorioFTP $ftpUser $ftpPassword $nomeItem;
            continue;       
            }
   
        $ftp = InstanciarFTPClient ($diretorioFTP+$nomeItem) $ftpUser $ftpPassword;
        $ftp.Method = [System.Net.WebRequestMethods+FTP]::UploadFile
        $ftp.KeepAlive = $false;
        $ftp.UseBinary = $true ;
        $ftp.UsePassive = $false;
       
        $responseStream = $ftp.GetRequestStream();                
            $bytesFile = [System.IO.File]::ReadAllBytes($item.FullName);
                   
        $responseStream.Write($bytesFile, 0, $bytesFile.Length);
        $responseStream.Close();
        $responseStream.Dispose();
    }
}

Espero que tenham gostado da dica! Winking smile

15 de nov. de 2011

Twitter + Silverlight ou WPF

Vamos fazer um cliente de Twitter???

Vamos!

Ebaaa...

image

Ok ok, comemorações a parte vamos iniciar.

A ideia aqui é usar a API do Twitter, fazendo simples requisições web, e aproveitar o potencial do XAML, a linguagem de interface por trás do Silverlight (inclusive do Windows Phone) e do WPF.

Então crie uma aplicação utilizando uma dessas tecnologias chamada de “MeuClienteDeTwitter”.

No exemplo foi utilizado WPF. Nossa UI ficará da seguinte maneira:

clip_image002

No “.xaml” principal/inicial (no caso do WPF o “MainWindow.xaml”), desenhe uma tela, arrastando os controles da Toolbox para a tela, com os seguintes controles:

  • TextBlock: Ao topo servindo de título para a aplicação. Altere a propriedade “Text” (para definir o valor do mesmo) e as propriedades de fonte, para deixar esse texto mais destacado. Esse controle funciona como uma Label do ASP.NET ou Windows Forms.
  • TextBox: Caixa de texto editável. Defina o nome dela como “txtUsuario”, acompanhe na imagem a seguir:
    clip_image004
  • Button: Botão para fazer a requisição e listar os tweets do usuário informado. Defina seu nome como “btnCarregar”.
  • ListBox: Lista de itens. Montaremos um layout para os itens que listaremos. Por hora nomeie-o como “lstConteudo”, e deixe seu fundo transparente, como na imagem abaixo:
    clip_image006

Curiosidade: O controle Label existe tanto no WPF como no Silverlight. Mas ele é um ContentControl, o que significa que ele pode conter “qualquer coisa” dentro delae não ficando limitado somente a texto puro e simples. Podemos adicionar um vídeo e imagem dentro da mesma Label, por exemplo. Como nesse exemplo queremos apenas texto para o título, optei pelo TextBlock.

Uma coisa importante quando definimos layout de telas com XAML é ficar atento ao painel de layout. Pois todos os controles são aninhados e organizados em um ou mais painéis. Há vários painéis, cada um com uma forma de organizar o layout diferente. Nesse caso, todos esses controles ficam dentro de uma Grid.

Essa Grid “não tem nada haver” com as conhecidas “DataGrids”, que montam tabelas com linhas e colunas proveniente de uma coleção de dados.

A Grid do XAML é um painel que se orienta por distancia das margens. Por exemplo: se colocarmos um botão em uma Grid, e definirmos ele com uma margem de 20 pixels na esquerda e 20 pixels na direita, não interessa o tamanho da janela ou o quanto ela for redimensionada, o controle se adaptará para manter a distancia das margens, sempre em 20 pixels próximo as bordas laterais.

A Grid pode ser dividida, criando bordas internas. Nesse exemplo, foi definida uma borda logo abaixo do botão e do campo de texto, para separar a ListBox dos demais controles. Assim, após colocar a ListBox na parte inferior, defini as margens dela como zero para todos os lados, logo ela acompanhará o tamanho da janela tanto em largura como em altura.

Bem, o intuito aqui não é ficar discutindo sobre esses painéis, em outra oportunidade eu falo mais dos mesmos.

Vejamos como ficou o XAML então:

<Window x:Class="MeuClienteDeTwitter.MainWindow"
        xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="484" Width="385">
    <!--Definindo o fundo em gradiente da janela-->
    <Window.Background>
        <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
            <GradientStop Color="LightBlue" Offset="0" />
            <GradientStop Color="White" Offset="1" />
        </LinearGradientBrush>
    </Window.Background>
    <Grid>
        <!--Definindo as linhas da grid para o layout.
        O "*" representa o tamanho que sobrar da jenala,
        após utilizar os 80 da linha de cima-->
        <Grid.RowDefinitions>
            <RowDefinition Height="80" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
       
        <Label Content="Meu Cliente de Twitter" Height="28" HorizontalAlignment="Left" Margin="12,12,0,0" Name="label1" VerticalAlignment="Top" FontWeight="Bold" FontSize="16" FontFamily="Verdana" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="12,46,0,0" Name="txtUsuario" VerticalAlignment="Top" Width="213" />
        <Button Content="Carregar o Twitter" Height="23" HorizontalAlignment="Left" Margin="231,46,0,0" Name="btnCarregar" VerticalAlignment="Top" Width="124" Click="btnCarregar_Click" />
       
        <ListBox Grid.Row="1" Name="lstConteudo" BorderBrush="{x:Null}" Background="{x:Null}">
            <!--Template que define o layout de cada item da ListBox-->
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <!--Perceba que foi utilizado um outro painel para definir o layout-->
                    <StackPanel Orientation="Horizontal" Height="132">
                        <Image Source="{Binding UrlFoto}" Height="73" Width="73" VerticalAlignment="Top" Margin="0,10,8,0" />
                        <StackPanel Width="370">
                            <TextBlock Text="{Binding Usuario}" Foreground="#FFC8AB14" FontSize="28"/>
                            <TextBlock Text="{Binding Conteudo}" TextWrapping="Wrap" FontSize="23"/>
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

Para fazer o fundo em gradiente, utilizamos o LinearGradientBrush com duas cores definidas para a Janela.

A primeira linha da Grid, que separa a ListBox dos demais controles do “cabeçalho”, tem 80 pixels de altura, o restante, definido como “*”, fica para a segunda linha que é onde está a ListBox.

Agora vem uma parte importante, a definição do layout dos itens que forem carregados no ListBox. Para isso temos que criar um painel de Layout, dentro do template de dados da ListBox.

Nesse caso o painel de layout utilizado foi o StackPanel, ou painel empilhador. Ele empilha os controles, um sobre o outro, seja na vertical ou na horizontal.

Dentro desse painel, colocamos um controle Image, para exibir a foto do usuário, com altura e largura de 73 pixels. Colocamos também dois TextBlock, um para o nome do usuário, com fonte um pouco maior, e outro para o tweet em si, com a quebra de linha ativada (propriedade “TextWrapping="Wrap"”).

Uma outra curiosidade: se você vem do desenvolvimento Windows Forms e quer uma maneira de organizar layout semelhante aos “bons e velhos” formulários, opte pelo painel chamado Canvas.

Ao analisar o XAML uma coisa deve estar te deixando cmo a pulga atrás da orelha: O que são aqueles “bindings”.

image

O pessoal do ASP.NET deve até desconfiar.

Bem, os bindings são definições de vinculo. Ou seja, nesse caso, passaremos uma lista de objetos para o ListBox. Esses objetos serão do tipo ItemTwitter, que criaremos mais adiante. Ou melhor, vamos cria-lo agora. Clique com o botão direito no projeto > Add > Class. Veja na imagem abaixo:

clip_image008

O nome dela será “ItemTwitter”, o código fonte está abaixo:

namespace MeuClienteDeTwitter
{
    public class ItemTwitter
    {
        public string UrlFoto { get; set; }
        public string Usuario { get; set; }
        public string Conteudo { get; set; }
    }
}

Basicamente três propriedades string estão definidas.

Voltando ao binding, quando passarmos para o ListBox uma lista do tipo ItemTwitter, para cada objeto da lista será criado um item no ListBox. Mas como vincular o layout com as informações dos itens da lista? Definindo um binding no controle e propriedade desejados. No caso da foto, colocaremos no controle Image, na propriedade Source (pois vincularemos a URL da foto do usuário). Nos TextBlocks a propriedade de vinculo será a Text.

No futuro falarei especificamente de binding.

Faltou definir a codificação para tudo funcionar. Então volte para o modo de desing e dê um duplo click no botão, assim será criado o evento click do mesmo.

Em seu click definiremos o seguinte código:

using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Xml.Linq;
 
namespace MeuClienteDeTwitter
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
       
        // -> Método do evento de click do botão para carregar os tweets.
        private void btnCarregar_Click(object sender, RoutedEventArgs e)
        {
            // -> Criamos um objeto que fará uma requisição web para a API do Twitter.
            var requisicao = new WebClient();
 
            // -> Concatenando o nome do usuário digitado na txtUsuario na URL da API do Twitter.
            var url = string.Format("
http://api.twitter.com/1/statuses/user_timeline.xml?screen_name={0}", txtUsuario.Text);
 
            /*
             -> Faremos a requisição web de forma assincrona, ou seja,
             * a requisição é disparada a aplicação não ficará travada até ela responder.
             * Mas quando ela responder, deve responder para a aplicação com um evento.
             * Então temos que definir o evento que ela responderá "requisicao_DownloadStringCompleted".
             * Agora podemos fazer a requisição assincrona, passando a URL da API, atravéz da classe URI.
             */
            requisicao.DownloadStringCompleted += new DownloadStringCompletedEventHandler(requisicao_DownloadStringCompleted);
            requisicao.DownloadStringAsync(new Uri(url));
        }
 
        void requisicao_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            // -> Todo o retorno do prossessamento da requisição virá na variável "e".
           
            // -> Verificamos se houve algum erro.
            if (e.Error != null)
                return;
 
            // -> o Retorno da requisição é um XML. Teste no seu navegador para averiguar.
            //      Então fazemos um parse nele para utilizar o LINQ.
            var tweets = XElement.Parse(e.Result);
 
            // -> Usando o LINQ, tranformamos os nós do XML em uma lista de objetos "ItemTwitter"
            var results = from tweet in tweets.Descendants("status")
                          select new ItemTwitter
                          {
                              UrlFoto= tweet.Element("user").Element("profile_image_url").Value,
                              Conteudo = tweet.Element("text").Value,
                              Usuario = tweet.Element("user").Element("screen_name").Value
                          };
 
            // -> Alimenta a ListBox.
            lstConteudo.ItemsSource = results.ToList();
        }
    }
}

Percebam que a API do Twitter nada mais é do que uma chamada HTTP que retorna um XML. Faça o teste no seu Navegador.

Após isso, utilizamos o LINQ para criar objetos, a partir do XML, e com eles alimentamos a ListBox, e está pronto nosso leitor de Tweets.

image

É praticamente a mesma coisa fazer essa App em Silverlight, inclusive coloca-la dentro de seu Windows Phone, veja aqui o Scott Gu fazendo isso:
http://weblogs.asp.net/scottgu/archive/2010/03/18/building-a-windows-phone-7-twitter-application-using-silverlight.aspx

Espero que tenham gostado. Alegre

26 de set. de 2011

Arquivos de Texto com Powershell

image

Rapidinho irei demonstrar como é fácil manipular arquivos de texto com Powershell, veja o código:

#region Manipulação de arquivos texto

    function LerTxt([string] $caminhoArquivo)
    {
        if(Test-Path $caminhoArquivo)
        {
            return Get-Content $caminhoArquivo;
        }
    }

    function EscreverTxt($caminhoArquivo, $conteudo)
    {
        New-Item $caminhoArquivo -type file -Force;
        Add-Content $caminhoArquivo $conteudo;
    }

#endregion

A única observação é que o código para gerar um arquivo de texto é recriado com o “new-item –force”. Caso desejem apenas adicionar conteúdo, desconsiderem essa linha.

Por hora fica essa dica the flash.

image

9 de set. de 2011

Mandando e-mail com Powershell

image

Quer algo mais cômodo do que você automatizar rotinas nos servidores e receber um aviso, status ou até mesmo log das operações no seu e-mail!?

Seu chefe desconfia que as rotinas estão rodando nos servidores? Coloque ele na cópia dos e-mails Winking smile! (Like a boss)

image

Ok, então fica registrado aqui uma função Powershell para envio de e-mails.

function SendMail([string] $smtpServer, [string] $smtpUser, [string] $smtpPassword, [string] $to, [string] $title, [string] $body)
{
    # -> Instancia um cliente SMTP.
    $smtp = new-object System.Net.Mail.SmtpClient;
   
    # -> Host do servidor SMTP.
    $smtp.Host = $smtpServer;
   
    # -> Autenticação no servidor SMTP.
    $smtp.Credentials = New-Object System.Net.NetworkCredential($smtpUser, $smtpPassword);
   
    # -> Instancia uma mensagem de e-mail.
    $message = New-Object System.Net.Mail.MailMessage;
   
    # -> Formata a mensagem para receber HTML.
    $message.IsBodyhtml = $true;
    $message.Body = $body;
    $message.Subject = $title;
   
    # -> Define o endereço de origem como o usuário que autenticou no servidor SMTP.
    $message.From = New-Object System.Net.Mail.MailAddress $smtpUser;
   
    # -> Quebra os endereços de destino de acordo com as separações (";").
    $toItems = $to.Split(";");
           
    foreach($toItem in $toItems)
    {
        # -> Adiciona os e-mails válidos de destino.
        if($toItem -ne $null -and $toItem.Trim() -ne "")
        {
            $toAdress = New-Object System.Net.Mail.MailAddress $toItem;
            $message.To.Add($toAdress);
        }
    }
           
    # -> Envia o e-mail.
    $smtp.Send($message);
}

Sem mais complicações, como já citei em outras oportunidades, o Powershell dispõe do poder das classes .NET. Então bata usá-las para essa tarefa Open-mouthed smile

Be happy!

8 de set. de 2011

Arranjo, Combinação e Permutação

image

Essas três palavrinhas fazem parte de clássicos da computação e matemática. então resolvi explicá-las e demonstrar com a linguagem C.

Arranjo: são grupos sem repetição, ou seja, se eu tenho os elementos 1, 2 e 3, eu posso agrupá-los em dupla (conjuntos de dois elementos) para formar os seguintes números: 12, 13, 21, 23, 31, 32.

O arranjo é a base da Combinação e da permutação. Sua fórmula é descrita assim:

A n,p = n!/(n-p)!

image

Onde “n” é o quantidade de elementos e “p” o tamanho do grupo.

No exemplo mencionado temos 3 elementos (quantidade) colocados em par (tamanho do grupo = 2).

A 3,2 = 3!/(3-2)! = 3.2.1/1! = 6

Agora que já entendemos a base, vamos para o próximo, a Combinação.

Combinação: é um Arranjo onde deveremos ignoramos os grupos que contenha os mesmo elementos, independente da ordem.

No exemplo do Arranjo, nós consideramos conjuntos distintos os números 12 e 21, porque numericamente são diferentes.

Mas imagine o caso onde temos um João e uma Maria. Tanto faz se o conjunto é (João, Maria) ou (Maria, João), pois formam o mesmo casamento Smile. Então essa é a Combinação: Arranjos que desconsideramos demais conjuntos que contenham o mesmo elemento independente da ordem.

C n,p = A n,p/p! = n!/p!(n-p)!

image

Percebam que é possível compor a fórmula da Combinação se baseando na fórmula do Arranjo.

Vamos ver um exemplo: Qual a quantidade de duplas possíveis com as pessoas Adriana, Xenofreuda e Tonha.

C 3,2 = 3!/2!(3-2)! = 3.2.1/2.1.1! = 3

E finalmente a Permutação.

Permutação: Arranjos onde a quantidade de elementos é igual ao tamanho do grupo, utilizado muito em anagramas. Anagramas são as variações possíveis de se fazer com as letras de uma palavra, por exemplo a palavra “mel”: mle, lme, lem, eml, elm.

Sua formula é um simples fatorial:

P n = n!

image

Para o exemplo:

P 3 = 3! = 3.2.1 = 6

Uma vez que entendemos a teoria, vamos colocá-la na pratica dentro da computação com a linguagem C.

Para isso, usei conceitos de Recursividade e Números Fatoriais.

// -> Para poder usar o "wcout" e o cout
#include<iostream>
using namespace std;

long double CalcularFatorial(int numero)
{
    if(numero < 2)
        return numero;

    return numero * CalcularFatorial(numero - 1);
}

long double CalcularArranjo(int quantidadeElementos, int tamanhoGrupo)
{
    return CalcularFatorial(quantidadeElementos)/CalcularFatorial(quantidadeElementos - tamanhoGrupo);
}

long double CalcularCombinacao(int quantidadeElementos, int tamanhoGrupo)
{
    return CalcularArranjo(quantidadeElementos, tamanhoGrupo)/CalcularFatorial(tamanhoGrupo);
}

long double CalcularPermutacao(int quantidadeElementos)
{
    return CalcularFatorial(quantidadeElementos);
}

void main()
{
    setlocale(LC_ALL, "Portuguese"); // -> Permitir acentos.

    while(true)
    {
        // -> Limpa a tela.
        system("cls");

        // -> Monta o menu de opções.
        wcout << "Qual operação deseja realizar?" << endl;
        wcout << "\t1-) Fatorial" << endl;
        wcout << "\t2-) Arranjo" << endl;
        wcout << "\t3-) Combinação" << endl;
        wcout << "\t4-) Permutação" << endl;
        wcout << "\t5-) Sair" << endl;
        wcout << "\tOpção: ";

        int opcao, quantidadeElementos, tamanhoGrupo;
        long double resultado;

        scanf("%i", &opcao);

        switch (opcao)
        {
            case 1:
                wcout << "Infome um número para calcular seu fatorial: ";
                scanf("%i", &quantidadeElementos);

                resultado = CalcularFatorial(quantidadeElementos);
                break;
            case 2:
                wcout << "Cálculo de Arranjo" << endl;
                wcout << "Infome a quantidade de elementos: ";
                scanf("%i", &quantidadeElementos);
                wcout << "Infome o tamanho do grupo: ";
                scanf("%i", &tamanhoGrupo);

                resultado = CalcularArranjo(quantidadeElementos, tamanhoGrupo);
                break;
            case 3:
                wcout << "Cálculo de Combinação" << endl;
                wcout << "Infome a quantidade de elementos: ";
                scanf("%i", &quantidadeElementos);
                wcout << "Infome o tamanho do grupo: ";
                scanf("%i", &tamanhoGrupo);

                resultado = CalcularCombinacao(quantidadeElementos, tamanhoGrupo);
                break;
            case 4:
                wcout << "Cálculo de Permutação" << endl;
                wcout << "Infome a quantidade de elementos: ";
                scanf("%i", &quantidadeElementos);

                resultado = CalcularPermutacao(quantidadeElementos);
                break;
        }

        if(opcao > 4) // -> Encerra a aplicação
            break;

        wcout << endl << "Resultado: " << resultado << endl << endl;
        wcout << "Pressione enter para continuar...";
        fflush(stdin);
        getchar();
    }

    wcout << endl << "Fim!";
    /*fflush(stdin);
    getchar();*/
}

Percebam que, como vimos na teoria, é possível aproveitar o Arranjo para compor a formula da Combinação, e fiz exatamente isso na função CalcularCombinacao().

Outro ponto é que, para os resultados eu tive que apelar para o tipo long double (96 bits), pois quando falamos em fatoriais, os números podem crescer freneticamente.

Acompanhe alguns testes:

image

image

É isso daí pessoal.

Já calcularam qual o números de combinações possíveis de maquiagem de maquiagem da sua namorada, mulher ou enrolada?

Você irá se surpreender O.o

7 de set. de 2011

Manipulando IIS com Powershell

image

Ultimamente tenho trabalhado bastante com Powerhell Powershell devido a uma consultoria no módulo de Build do TFS. O legal desse módulo é que você pode interagir com scripts Powershell e variáveis do Work Flow que o TFS utiliza durante um build.

O Powershell é muito poderoso, isso se deve ao fato dele usufruir das classes .NET, utilizar o Windows Remote Management (WinRM) para execução remota de scripts, e comandos nativos das versões mais atuais do prompt, como o ROBOCOPY.

image

Assim como no .NET, nós podemos instalar módulos adicionais, e até mesmo importar os já instalados. No caso do IIS devemos importar o módulo “WebAdministration” . Então segue alguns scripts para manipulação do IIS.

Import-Module WebAdministration;

#region Manipulação do IIS
       
    function PararPool([string] $poolName)
    {
        Stop-WebAppPool -Name $poolName;
    }
       
    function IniciarPool([string] $poolName)
    {
        Start-WebAppPool -Name $poolName;
    }
       
    function PararSite([string] $siteName)
    {
        $site = GetSite $siteName;
        $site.Stop();
    }
       
    function IniciarSite([string] $siteName)
    {
        $site = GetSite $siteName;
        $site.Start();
    }
       
    function GetSite($siteName)
    {   
        $site = Get-Item IIS://Sites/$siteName -ErrorAction SilentlyContinue;
        return $site;
    }
       
    function GetDirectorySite($site)
    {
        (Get-Item IIS://Sites/$site).PhysicalPath;
    }
       
    function GetPoolSite($site)
    {
        $objSite = Get-Item IIS://Sites/$site;
        return $objSite.ApplicationPool;
    }
       
    function CriarSite([string] $siteName, [string] $caminho)
    {
        New-Item IIS:\AppPools\$siteName;
        New-Item IIS:\Sites\$siteName -bindings @{protocol="http";bindingInformation=":80:$siteName"} -physicalPath $caminho;
        Set-ItemProperty IIS:\Sites\$siteName -name applicationPool -value $siteName;
    }
       
#endregion

Os scripts foram testados no IIS 7 e 7.5.

image

É lógico que existem mil e uma maneiras de preparar neston atingir um objetivo.

image

É possível utilizar o Active Directory Service Interfaces (ADSI), ou até mesmo o Windows Management Instrumentation (WMI). Acompanhe como reciclaríamos um determinado pool do IIS com o ADSI:

function ReciclarPool([string] $server, [string] $poolName)
{           
    ([adsi]"IIS://$server/W3SVC/AppPools/$poolName").Recycle();
}

Uma última dica por hora, para editar e depurar scripts powershell, estou usando o programa PowerGUI.

image

É isso daí pessoal. Por hora é só, espero que tenham gostado! Smile

3 de ago. de 2011

Deletar arquivo do dia anterior

pinky-e-cerebro

Dica rápida…

A alguns dias dias atrás a equipe de desenvolvimento com a qual estava trabalhando decidiu persistir o Viewstate do ASP.NET no HD do servidor.

Após implantar as configurações, rotinas e afins, ficou a dúvida se as rotinas de exclusão dos viewstates antigos estava funcionando corretamente.

Um desenvolvedor deu a ideia de criar um .exe que excluísse os arquivos do dia anterior. Logo pensei: que mania de desenvolvedor de achar que o mundo pode ser resolvido com um .exe. (Falo isso com toda a autoridade de ser um desenvolvedor também!)

Então eu intervi, dizendo que apenas persistissem, e eu agendaria uma tarefa no servidor Windows para apagar os viewstates do dia anterior.

Mas… #comofaz?

Como estou trabalhando bastante com Poweshell ultimamente, pensei que não seria difícil desenvolver um script assim.

Após pesquisar um pouco descobri o comando "forfiles" do prompt do Windows mesmo. Essa belezinha lista arquivos, podendo aplicar alguns filtros. O filtro para os dias é o parametro "D", onde nesse caso, defini –1, veja:

image

#Maravawonderfull, listei os arquivos, mas e agora, como deletá-los? Já pensou que agonia, colocá-los em variáveis  de script basic/bat!?

#Esgurmita!

Puxei um help do comando e loco descobri que havia como passar um comando para aplicar a cada item listado.

Com mais alguns parâmetros consegui gerar um .bat e agendar no Windows a rotina para executá-lo diariamente:

forfiles /P "C:\Users\Spoky\AppData\Local\Temp" /S /M *.txt /D -1 /C "cmd /c del @file"

Onde:

  • P: Diretório da da listagem.
  • S: Busca recursiva pelos diretórios a dentro.
  • M: Aplica a máscara *.txt.
  • D: Data da modificação.
  • C: Aplica algum comando para cada resultado da listagem.

Então #FicaDica Smiley piscando

25 de jul. de 2011

Auditoria no TFS - PT II

Antes de continuar com as dicas de auditoria, gostaria de ratificar que a dica prestada no post "Auditoria no TFS - PT I" só é possível usando o TFS Power Tools, um conjunto de ferramentas que aprimoram a experiência e interação com o TFS. Valeu @wsilva81 por ter me lembrado desse detalhe.

E aqui vai mais uma dica de outra ferramenta que auxilia na auditoria do TFS. É o TFS Membership Visualizer. Ele monta um gráfico, baseado no gráfico de dependência do Visual Studio 2010, com informações de Team Projects de uma collection. É possível adicionar o plug-in no Visual Studio como nas imagens abaixo:

10

11

Após instalado, siga os seguintes passos para gerar o gráfico:

1

2

3

4

Assim obtemos o seguinte resultado:

5

Quem merece atenção no gráfico são as imagens roxas, que indicam os logins e grupos que tem acesso aos Team Projects. Mas também auxiliam em outras situações para visualização da collection, team projects, source controls etc.

#FicaDica Smiley piscando

23 de jul. de 2011

Transformation de web.config

ultimate_bumblebee

Transformation de arquivos de configuração é uma feature que surgiu com o Visual Studio de 2010. São arquivos de configurações que complementam o arquivo de configuração original. Esse complemento pode ser a adição, remoção e a transformação de tags do arquivo original.

Esses complementos são bem vindos quando precisamos gerar builds para ambientes distintos. Se sua empresa trabalha com cenários de testes, homologação, produção, etc… Pode gerar um transformation para cada um desses cenários, alterando a tag de connection string com o banco de dados por exemplo.

Ao criarmos um projeto web no Visual Studio, temos de cara as configurações de debug e release.

1

Ao abrir o arquivo de release, podemos ver que, diferentemente do web.config, o web.release.config não tem tantas tags, apenas instruções para as transformações das tags desejadas.

2

Para criamos mais uma variação do web.config, primeiro criamos um cenário:

3

4

Durante a criação definiremos o nome do ambiente, e também podemos definir se ele se baseará em um ambiente existente.

5

Com o ambiente criado, podemos adicionar o arquivo de configuração desse ambiente.

6

7

Vamos abrir o arquivo original e adicionarmos algumas configurações.

8

Observe a origem do web.config original. Ele já veio com connection string, e adicionei duas "appSettings".

Agora, definiremos o arquivo web.teste.config assim:

<?xml version="1.0"?>

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">   <connectionStrings>     <add xdt:Transform="RemoveAll" />   </connectionStrings>   <appSettings>     <add key="Numero1" value="2" xdt:Transform="Replace" xdt:Locator="Match(key)"/>     <add key="Numero2" value="3" xdt:Transform="Replace" xdt:Locator="Match(key)"/>   </appSettings>   <system.web>     <compilation xdt:Transform="RemoveAttributes(debug)" />   </system.web>    </configuration>



Regras para o tranformation:




  • Sempre respeite a hierarquia da tag, no exemplo das tags "Numero1" e "Numero2", elas tem que estar dentro da tag "appSettings".


  • Para aplicar o transformation tem que usar o atributo "xdt:Transform".


  • Clique aqui para obter vários exemplos de sua aplicação.



No exemplo citado foram removidas qualquer connection string pelo "RemoveAll" e alteradas ("Replace") algumas configurações do "appSettings", que foram localizadas pelo atributo "key" ("Match(key)").



Vamos gerar o build para ver se funciona?



Então gere uma publicação:



9



10



Reparem na imagem acima, que a build configuration é a Teste, que acabamos de criar.



Após publicarmos, olhem o resultado:



11



12



Temos um novo web.config transformado/mesclado.



E isso se reproduz quando utilizamos o mecanismo de build do TFS. Mas esse caso fica para a próxima! Smiley de boca aberta