jueves, 25 de octubre de 2012

Limpiar WSUS de las descargas (útil si usas SCCM)

Enunciado

Instalas WSUS y configuras la descarga de actualizaciones aprobadas.
Las apruebas.
Instalas luego SCCM y descubres que realmente no quieres que no necesitas descargar las aplicaciones.
Estas duplicando el espacio en disco.
(Para SCCM se debe instalar WSUS pero no configurarlo)

Solución

Tan simple como marcar todas las descargas como rechazadas o no aceptada y ejecutar el asistente de limpieza en opciones.

Paquetes de definiciones EndPoint Protection 2012 vacios

Síntomas:

English Version at MSDN Forums.

En System Center Configuration Manager 2012 con un servidor SQL Server español las reglas para la distribución automática de paquetes con definiciones de End Point Protection nunca se rellenan con las actualizaciones del WSUS.

Cuando analizas el rulengine.log encuentras estas entradas:
Query to run is: select CI_ID from dbo.fn_ListUpdateCIs(3082) ci~where IsExpired=0~ and (DateRevised>=N'2012-10-23 22:22:08')~ and (CI_ID in (select CI_ID from fn_ListCICategoriesAll(3082) where CategoryTypeName='Product' and (CategoryInstanceName in (N'Forefront Endpoint Protection 2010')))) SMS_RULE_ENGINE 25/10/2012 0:22:08 3136 (0x0C40)
Rule resulted in a total of 0 updates SMS_RULE_ENGINE 25/10/2012 0:22:09 3136 (0x0C40)

Solución:

En mi caso bastó con cambiar el idioma prederminado del SQL Server a Inglés ( en propiedades del servidor motor de BD, Avanzadas, Idioma por defecto).
Para ver si es tu caso lee los siguientes comentarios.

Comentarios:

Si te fijas en la primera línea del registro, a continuación del Query to run is:  tenemos una clausula SQL que podemos copiar y pegar en la en la consola (SSMS) del SQL Server. Una vez eliminado los símbolos ~   y con unos saltos de línea queda bastante legible.
select CI_ID from dbo.fn_ListUpdateCIs(3082) ci 
where IsExpired=0  
 and (DateRevised>=N'2012-10-23 22:22:08')  
 and (CI_ID in (select CI_ID from fn_ListCICategoriesAll(3082) 
                where CategoryTypeName='Product' 
                and (CategoryInstanceName in (N'Forefront Endpoint Protection 2010')
))) 
Pero si la ejecutamos tenemos un  un error:

CI_ID
-----------
Mens. 242, Nivel 16, Estado 3, Línea 1
La conversión del tipo de datos nvarchar en datetime produjo un valor fuera de intervalo.

Este error debería desaparecer si cambias en la consulta el formato de fecha (En lugar de 2012-10-23 escribes 23-10-2020).

select CI_ID from dbo.fn_ListUpdateCIs(3082) ci 
where IsExpired=0  
 and (DateRevised>=N'23-10-2012 22:22:08')  
 and (CI_ID in (select CI_ID from fn_ListCICategoriesAll(3082) 
                where CategoryTypeName='Product' 
                and (CategoryInstanceName in (N'Forefront Endpoint Protection 2010')
))) 
Obtendrás la lista de ids de definiciones, en mi caso fué:
CI_ID
-----------
16811415
16811428
16811468

(3 filas afectadas)
Por eso si cambias el idioma predeterminado a inglés del SQL Server te funcionara la ADR de SCCM.

Nota:

En mi caso opté por cambiar el idioma en el servidor  pero es posible que cambiándolo en los usuarios de SCCM o el origen de datos ODBC del servidor SCCM se resuelva también el problema.

viernes, 19 de octubre de 2012

Algunos consejos instalando SCCM con End Point Security Manager

Enunciado:

Instalar MS End Point Protection Manager con System Control Configuration Manager es una tortura (http://angrytechnician.wordpress.com/2010/08/09/the-torture-of-installing-system-center-essentials-2010/)
Espero que las siguientes notas sean de ayuda:

Problema 1:

La collation del SQL Server debe ser SQL:Latin1_General_CP1_CI_AS. 
Lo debes especificar al instalar el SQL SERVER

Si como yo procedes a instalar con los valores por defecto tendras que:

  • Desinstalar WSUS completamente si ya lo has instalado como hice yo.
  • Realizar un rebuild de la base MASTER

Para ello usas este mandato:
Setup /QUIET /ACTION=REBUILDDATABASE /INSTANCENAME=InstanceName /SQLSYSADMINACCOUNTS=accounts [ /SAPWD= StrongPassword ] [ /SQLCOLLATION=CollationName]


  • Volver a configurar las bases de datos del Report Server
  • Reinstalar WSUS

Problema 2

La documentación para configurar las actualizaciones de Windows Update no esta muy clara, puedes seguir este tutorial:
http://www.windows-noob.com/forums/index.php?/topic/5452-using-system-center-2012-configuration-manager-part-1-installation-cas/
y mejor que no te dejes nada de las primeras páginas.

Problema 3

Cuando configuras la primera máquina para que descargue el cliente SCCM, se produce un error. En mi caso es que no había configurado un Boundary Group. Al configurarlo le dices con que servidores tiene que conectar.

Realmente es una tortura.

miércoles, 10 de octubre de 2012

DisplayMember en windows forms checkedlistbox

Problema:

 El control checkedlistbox de de Windows Forms no me ofrece los atributos "Displaymember" o "Valuemember" en las ventana de propiedades o en la lista inteligente de código.

Solución:

Establecerlo en código aunque no aparezca en la lista. Existe pero está marcado como no browseable.
!Atención¡ Escribe bien las mayúsculas y minúsculas.

Ejemplo;

miCheckedListBox.DisplayMember="Descripcion"

Referencia:

lunes, 1 de octubre de 2012

Chekbox en windows forms solo lectura

Enunciado

A diferencia de otros controles de Windows forms las checkbox no pueden marcarse como de solo lectura (readonly). Si utilizas la propiedad Enabled, pasan a un color gris claro que se ve mal, y no es modificable.

Solución:

Coloca las casillas dentro de un panel (por ejemplo panel1)
Importa la función WindowEnabled de user32.dll para poder deshabilitar eventos de ratón y teclado en ese panel.
Imports System.Runtime.InteropServices
Public Class Form1
    <DllImport("user32.dll")> _
    Private Shared Function EnableWindow(hWnd As IntPtr, bEnable As Boolean) As Boolean
    End Function

    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        EnableWindow(Panel1.Handle, False)
    End Sub

martes, 18 de septiembre de 2012

Formula para repartir los mismos puntos en una lista de longitud variable

Enunciado:

Realizas una encuesta con preguntas donde te responde con una lista de longitud variable por orden de preferencia.
Quieres repartir una cantidad fija de puntos entre las respuestas dando mas siempre a las situadas en primer lugar.

Por ejemplo "elija su ciudad favorita". En una respuesta te dicen solo una "CASTELLÓN", otra persona te dice "MADRID", "BARCELONA", "VALENCIA" y una tercera te dice "MADRID", "VALENCIA". "SEVILLA", "BURRIANA"
Hay 100 puntos a repartir, veamos los resultados:
  • La primera respuesta dará a CASTELLÓN 100 puntos
  • La segunda entregará  50 puntos a MADRID, 33 a BARCELONA y 17 a VALENCIA.
  • La tercera entrega a 40 a MADRID,  30 a VALENCIA, 20 a SEVILLA y 10 a BURRIANA
Al final tenemos: CASTELLON (100), MADRID (73), VALENCIA (47),BARCELONA (33) y BURRIANA (10).
Gana CASTELLON a MADRID, pese que CASTELLON solo haya sido votada una vez, y MADRID dos veces y en primer lugar en ambos casos.
Se valora mas cuando solo se da una respuesta que si se responde con varias. La persona que ha votado a CASTELLON está muy convencida, mientras que las demás tienen gustos dispersos.

Se me ocurre aplicarlo en las carreras de los autos locos, los participantes puntúan mas cuantos menos coches acaban. Seria peligroso aplicarlo en la F2 (Fernando Alonso dixit).

Solución

puntuación(r,p)=2*( (r-p+1)/(r*(r+1)))

Donde r es el número de respuestas y p la posición de la respuesta que estamos puntuando.

Comentario 

Esta formula puede implantarse en SQL  o en MDX. Es fácil construir una tabla Excel para ver las puntuaciones.


Cómo puede verse me apoyo en la suma de la serie geometríca.

Archivos duplicados y hash MD5

Enunciado

Quieres detectar y mover a una carpeta todos los archivos duplicados en una carpeta y subcarpetas. 
Cuando hay duplicidados mueves el archivo con nombre mas largo o que está en una subcarpeta.
En la nueva carpeta creas las subcarpetas originales.

Solución:

Para detectar los archivos duplicados usamos el hash MD5 calculado con la clase correspondiente en el framework .NET, recorremos recursivamente las carpetas, comparando archivos  y moviendo el que tiene path completo mas largo.
Const pathdup="c:\duplicados" 'carpeta donde se moveran los duplicados
Sub procesaCarpeta(carpeta As String)
'carpeta: carpeta a recorrer
   Dim existencias As Dictionary(Of String, String)
    Dim Md5 As New MD5CryptoServiceProvider()
        Try
            Dim archivos = My.Computer.FileSystem.GetFiles(carpeta)

            For Each archivo In archivos
                Dim acont = My.Computer.FileSystem.ReadAllBytes(archivo)
                Dim clave = Convert.ToBase64String(Md5.ComputeHash(acont))
                If existencias.ContainsKey(clave) Then
                    If existencias(clave).Length <= archivo.Length Then
                        'mover nuevo
                        My.Computer.FileSystem.MoveFile(archivo, archivo.Replace("C:\", pathdup))
                    Else
                        My.Computer.FileSystem.MoveFile(existencias(clave), existencias(clave).Replace("C:\", pathdup))
                        existencias(clave) = archivo
                    End If
                Else
                    existencias.Add(clave, archivo)
                End If
            Next
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.OkOnly, carpeta)
        End Try

        For Each hija In My.Computer.FileSystem.GetDirectories(carpeta)
            procesaCarpeta(hija)
        Next
    End Sub

Comentario

Puede parecer tonto pero limpié 7 Gb del disco duro de mi casa. La explicación es simple, mi hija antes de editar copiaba todas las imágenes de una carpeta y las pegaba en la misma carpeta o en una  subcarpeta (a veces ambas cosas).