VM template@Windows Server 2012

W2012

El quid de la cuestión es el siguiente: La necesidad de crear una VM que haga de “base canónica” para desplegar múltiples roles dentro de una infraestructura virtualizada y, de esa manera, ahorrarse una cantidad de tiempo importante que se perdería instalando el sistema operativo sendas veces.

Para esto los pasos a seguir son los siguientes:

  • Instalar Windows Server 2012 en una VM dentro de Hyper-V
  • Instalar las actualizaciones correspondientes
  • Correr el comando sysprep
  • Apagar la VM
  • Copiar la VM “base canónica” para usarla en de template en las VM´s a crear

Comando a ejecutar para realizar Sysprep:

post1

post3

pos4

Ejecutando Sysprep

post3

infra

VM´s creadas a partir de template

Ahora, a seguir con el resto del trabajo.

:wq!

IMAP <-> PHP

popimap

Hoy tuve la necesidad de investigar como descargar correos de un servidor IMAP a través de PHP. Para esto existen una serie de funciones disponibles que se listan aqui.

Para hacer la prueba que necesitaba instale el software XAMPP para tener a disposición un APACHE con PHP. El primer problema que tuve fue que la librería no esta habilitada por defecto, entonces debemos descomentar la siguiente linea en el archivo php.ini:

Luego, haciendo uso de algunas funciones nos conectamos al servidor, listamos las casillas y descargamos un correo:

<?php
    $hostname = '{imap.gmail.com:993/imap/ssl}';
    $username = 'tucorreo@gmail.com';
    $password = 'passw0rd';
 
    /* Abrimos conexion con le servidor */
    if($inbox = imap_open($hostname,$username,$password) or die('No se pudo conectar con el servidor  '.$hostname.': '.imap_last_error())){
        echo "&#91;crayon-597380034b49a870738288/&#93;";
         
     
        $boxes = imap_list($inbox, $hostname, "*");
 
        echo "&#91;crayon-597380034b4a1783016786/&#93;";
           
        $header = imap_header($inbox, 1000); // Traemos el header del mail 1000 de la casilla INBOX
        echo "&#91;crayon-597380034b4a6723853735/&#93;";
           
        imap_close($inbox); // Cerramos la conexion
   
    }
?>

Output:

Array
(
    [0] => {imap.gmail.com:993/imap/ssl}Club Corredores
    [1] => {imap.gmail.com:993/imap/ssl}Facebook
    [2] => {imap.gmail.com:993/imap/ssl}INBOX
    [3] => {imap.gmail.com:993/imap/ssl}Personal
    [4] => {imap.gmail.com:993/imap/ssl}Recibos
    [5] => {imap.gmail.com:993/imap/ssl}Trabajo
    [6] => {imap.gmail.com:993/imap/ssl}Viaje
    [7] => {imap.gmail.com:993/imap/ssl}[Gmail]/Borradores
    [8] => {imap.gmail.com:993/imap/ssl}[Gmail]/Destacados
    [9] => {imap.gmail.com:993/imap/ssl}[Gmail]/Enviados
    [10] => {imap.gmail.com:993/imap/ssl}[Gmail]/Importante
    [11] => {imap.gmail.com:993/imap/ssl}[Gmail]/Papelera
    [12] => {imap.gmail.com:993/imap/ssl}[Gmail]/Spam
    [13] => {imap.gmail.com:993/imap/ssl}[Gmail]/Todos
)
stdClass Object
(
    [date] => Sat, 31 Dec 2005 06:37:51 +0000
    [Date] => Sat, 31 Dec 2005 06:37:51 +0000
    [subject] => [Slashdot] Stories for 2005-12-31
    [Subject] => [Slashdot] Stories for 2005-12-31
    [message_id] => <1136010604.842534-32059-slash-slashdot-nfs-1.osdn.net@slashdot.org>
    [toaddress] => delfox@gmail.com
    [to] => Array
        (
            [0] => stdClass Object
                (
                    [mailbox] => delfox
                    [host] => gmail.com
                )
 
        )
 
    [fromaddress] => slashdot@slashdot.org
    [from] => Array
        (
            [0] => stdClass Object
                (
                    [mailbox] => slashdot
                    [host] => slashdot.org
                )
 
        )
 
    [reply_toaddress] => slashdot@slashdot.org
    [reply_to] => Array
        (
            [0] => stdClass Object
                (
                    [mailbox] => slashdot
                    [host] => slashdot.org
                )
 
        )
 
    [senderaddress] => slashdot@slashdot.org
    [sender] => Array
        (
            [0] => stdClass Object
                (
                    [mailbox] => slashdot
                    [host] => slashdot.org
                )
 
        )
 
    [Recent] =>  
    [Unseen] => U
    [Flagged] =>  
    [Answered] =>  
    [Deleted] =>  
    [Draft] =>  
    [Msgno] => 1000
    [MailDate] => 31-Dec-2005 06:37:52 +0000
    [Size] => 26823
    [udate] => 1136011072
)

Para sacarle jugo, es cuestión de seguir jugando.

:wq!

Impresión 3D de órganos humanos?

ted

Hay muchas charlas TED que no dejan nada, que te hacen sentir que perdiste 15/30 minutos de tu vida. También hay otras como esta, que te dejan la cabeza volando por los aires. Si bien esta exposición tiene un tiempo ya, quería compartirlo. Da gusto ver esta sinergia de disciplinas…

Imagino será de especial interés para aquellos que estudien biotecnología y afines.

Producción de órganos humanos: Músculos, vasos sanguíneos, vejigas, entre otros.

Parte I

Parte II

 

Saludos!

Migración de usuarios por dominio – Lync 2010

Durante una migración con una topologia similar a la del diagrama que se adjunta, me cruce con el problema siguiente: La migración debía respetar un procedimiento que planteaba una ventana de varias semanas en donde, a cada paso se debían migrar los usuarios de un dominio particular y luego validarlos en los servidores de destino para luego seguir con los demás usuarios. El problema de este procedimiento es que la herramienta que provee Lync 2010 para exportar la base de datos de usuario es:

Y esta herramienta Dbimpexp.exe exporta absolutamente todos los usuarios del pool. Ante este panorama investigue un poco que otras opciones tenia pero no encontré nada que me sirviera, por lo que opte por desarrollar un pequeño script que interpretara la estructura del archivo XML que utiliza Lync 2010 y que armara una salida con los usuarios del dominio que yo quisiera.

postLync3

 *  Busqueda de dominio en un archivo
 *  XML dada la siguiente estructura:
 *  <HomedResources>
 *      <HomedResource UserAtHost="dominio">
 *      </HomedResource>
 * </HomedResources>

Para esto, antes debía validar que se pudiera importar usuarios en cantidades distintas de “1” o “todos”, que es lo soportado por el procedimiento estándar.

impexp

Una vez analizada la estructura XML y validado el procedimiento a ejecutar empece a ver como me convenía parsear el documento. Por suerte, PHP cuenta con una librería muy amigable llamada SimpleXML que facilito muchísimo la tarea. El script resultante es el siguiente:

<?php
/*********************************************
 *
 *  Busqueda de dominio en un archivo
 *  XML dada la siguiente estructura:
 *  <HomedResources>
 *      <HomedResource UserAtHost="dominio">
 *      </HomedResource>
 * </HomedResources>
 *
 * *******************************************/
 
// Declaro el dominio que quiero buscar
$dominioABuscar = 'dominio.com.ar';
$recursosEncontrados = array();
 
// Obtengo el contenido del archivo xml
$file = file_get_contents('Skanska1.xml');
 
// Creo un objeto SimpleXml con el contenido del archivo
$resources = simplexml_load_string($file);
 
// Leo todo los recursos
foreach ($resources as $resource)
{
    $host = $resource['UserAtHost']; // me quedo con el host del recurso actual
 
    list($user, $dominio) = explode('@', $host); // separo el dominio de host
 
    if ($dominio == $dominioABuscar)
    {
        $recursosEncontrados[] = $resource;
    }
}
 
if (!empty($recursosEncontrados))
{
    $stringResult = '';
 
    // Genero los resultados como string
    foreach ($recursosEncontrados as $recurso)
    {
        // Genero el output en una variable
        $stringResult .= $recurso->asXml() . "\n";
    }
 
 
    // Variables para el archivo de salida
    $path          = '/var/www';
    $fileExtension = '.xml';
    $fileName      = $dominioABuscar . '_' . date('d-m-Y') . $fileExtension;
    $pathResult    = $path . $fileName;
 
    // Creo el archivo de resultados
    $fileResult = fopen($pathResult, 'x');
    fwrite($fileResult, $stringResult); // Escribo los resultados en el archivo
    fclose($file); // Cierro el archivo
 
    if (file_exists($pathResult))
    {
        $output = "Archivo creado correctamente. <a href='$pathResult'>$fileName</a>";
    } else {
        $output = "El archivo no se ha creado correctamente.";
    }
 
} else {
    $output = "No se encontraron recursos para el dominio <b>" . $dominioABuscar . "</b>";
}
 
echo $output;
?>

El output de este script se ve algo así:

postLync2

Luego, este documento se importa en Lync 2010 con la herramiente Dbimpexp.exe y listo!

Un ultimo detalle, a este documento que genera el script, se le debe cerrar el tag global:



[/html] Mi experiencia personal fue exitosa y logre el cometido, no se en que otros contextos será provechoso este procedimiento, pero cualquier comentario es bienvenido. :wq!

Understanding Front End pool pairing – Lync 2013

Comparto un vídeo donde se explica como hacer un deployment de la nueva característica de HA que trae Lync 2013 “Pool Pairing” para escenarios de disaster recovery en contextos de sitios separados geográficamente. Esta característica permite, gracias a una constante sincronizacion entre los Front End de los pools, comenzar a registrar usuarios pertenecientes a un pool caído desde el momento en que se ejecuta el procedimiento correspondiente de forma manual

El CMS actual será reemplazado por el existente en la instancia definida sobre el servidor redmond-cs-001.litwareinc.com. En el caso de un standard edition pool es exactamente lo mismo.

postLync

Escenario disaster recovery

Video

Enlaces relacionados:

:wq!