sabato 8 novembre 2008

Aggiungere utenti in Team Foundation Server

Dopo l'installazione di Team Foundation Server è necessario aggiungere utenti per poter operare sul server. Per impostazione predefinita, l'account utente utilizzato durante l'installazione viene aggiunto di default.

Tutte le edizioni di Team Foundation Server richiedono che gli utenti siano membri di un gruppo di Team Foundation Server a livello di progetto o server. Il livello e il gruppo dipendono dalle funzionalità che si desidera attivare per l'utente. Se ad esempio si desidera che un utente sia in grado di creare un progetto Team, l'utente deve disporre dell'autorizzazione Crea nuovi progetti impostata su Consenti, deve essere assegnato al ruolo di Gestione contenuto in SQL Server Reporting Services e al ruolo di Amministratore per Windows SharePoint Services. Non è tuttavia necessario che sia membro del gruppo di amministratori locali nel computer. Per ulteriori informazioni su utenti e ruoli, vedere l'argomento "Autorizzazioni di Team Foundation Server" nella guida dell'amministratore di Team Foundation Server.


Per aggiungere utenti a Team Foundation Server:
  1. Accedere come amministratore di Team Foundation, aprire Team Explorer e connettersi al server Team Foundation Server a cui si desidera aggiungere un utente.

  2. Scegliere Impostazioni di Team Foundation Server dal menu Team, quindi Appartenenza a gruppo.

  3. Nella finestra di dialogo Gruppi globali scegliere Utenti con licenza Team Foundation, quindi Proprietà.

  4. Nella finestra di dialogo delle proprietà Gruppo Team Foundation Server scegliere Utente o gruppo Windows, quindi Aggiungi.

  5. Nella finestra di dialogo Selezione utenti o gruppi digitare gli account utente che si desidera aggiungere, quindi scegliere OK.

  6. Scegliere Chiudi.


Note
Non è possibile utilizzare la finestra di dialogo del gruppo Sicurezza globale per aggiungere utenti al gruppo. È possibile aggiungere singoli account utente, ma non un account di gruppo.
ProtezionePer eseguire questa procedura, è necessario essere membro del gruppo Administrators di Team Foundation

Con questa procedura, però, l'utente sarà solo in grado di connettersi al server, ma non potrà né accedere a progetti esistenti né crearne di nuovi. Per terminare correttamente la configurazione è possibile ricorrere al programma TFS Admin Tool. È un programma che permette ad un amministratore TFS di aggiungere velocemente utenti alle tre piattaforme utilizzate dal Team Foundation Suite (Team Foundation Server, Sharepoint e SQL Reporting Services) attraverso una singola interfaccia comune. Il programma permette anche di cambiare i permessi assegnati agli utenti e di identificare gli eventuali errori.


Il programma è scritto in C# ed è pubblicato su CodePlex.

    martedì 4 novembre 2008

    Asterisk / Trixbox: ascolto chiamate in corso

    Con Asterisk o Trixbox è possibile ascoltare le chiamate in corso effettuate o ricevute da altri client.

    In "extensions.conf" in un contesto di vostro piacimento inserite questa riga. Se usate Trixbox o @home mettetelo in "extensions_custom.conf "sotto a [from-internal-custom]

    per esempio:

    exten => _61XXX,1,ChanSpy(SIP/${EXTEN:2},q)

    con tante X quante sono le cifre o i caratteri componenti i "nomi" dei vostri interni (in questo caso 3)

    Un bel reload, e poi bastera digitare sulla tastiera del telefono 61206 per ascoltare le telefonate dell’interno 206

    Asterisk / Trixbox: registrazione chiamate

    Con Asterisk o Trixbox è possibile registrare le chiamate effettuate da client.
    Per farlo basta inserire queste righe nel file "extesion.conf" su Asterisk oppure in "exstension_custom.conf" su Trixbox. (PS: su Trixbox è possibile abilitare questa funzione anche da interfaccia grafica)

    exten => _61XXX,1,Monitor(wav,rec${EXTEN:2},m)
    exten => _61XXX,2,ChanSpy(SIP/${EXTEN:2},q)
    exten => _61XXX,3,Hangup

    in /var/spool/asterisk/monitor troveremo le registrazioni in formato wav con nome rec"numinterno"

    E' anche possibile visualizzarle da web facendo un link simbolico della dir in var/www/dove volete

    giovedì 16 ottobre 2008

    Select Distinct su DataSet in Vb.Net

    Le funzioni sotto riportate permettono di effettuare da codice una query con "Select Distinct" su un DataSet.

    FieldNames è un array di string con in campi su cui fare la select distinct.



    Public Function SelectDistinct(ByVal SourceTable As DataTable, _
        ByVal ParamArray FieldNames() As String) As DataTable

        Dim lastValues() As Object
        Dim newTable As DataTable

        If FieldNames Is Nothing OrElse FieldNames.Length = 0 Then
            Throw New ArgumentNullException("FieldNames")
        End If

        lastValues = New Object(FieldNames.Length - 1) {}
        newTable = New DataTable

        For Each field As String In FieldNames
            newTable.Columns.Add(field, SourceTable.Columns(field).DataType)
        Next

        For Each Row As DataRow In SourceTable.Select("", String.Join(", ", FieldNames))
            If Not fieldValuesAreEqual(lastValues, Row, FieldNames) Then
                newTable.Rows.Add(createRowClone(Row, newTable.NewRow(), FieldNames))
                setLastValues(lastValues, Row, FieldNames)
            End If
        Next

        Return newTable
    End Function



    Private Function fieldValuesAreEqual(ByVal lastValues() As Object, _
        ByVal currentRow As DataRow, ByVal fieldNames() As String) As Boolean

        Dim areEqual As Boolean = True

        For i As Integer = 0 To fieldNames.Length - 1
            If lastValues(i) Is Nothing OrElse Not lastValues(i).Equals(currentRow(fieldNames(i))) Then
                areEqual = False
                Exit For
            End If
        Next

        Return areEqual
    End Function



    Private Function createRowClone(ByVal sourceRow As DataRow, _
        ByVal newRow As DataRow, ByVal fieldNames() As String) As DataRow

        For Each field As String In fieldNames
            newRow(field) = sourceRow(field)
        Next

        Return newRow
    End Function



    Private Shared Sub setLastValues(ByVal lastValues() As Object, _
        ByVal sourceRow As DataRow, ByVal fieldNames() As String)

        For i As Integer = 0 To fieldNames.Length - 1
            lastValues(i) = sourceRow(fieldNames(i))
        Next
    End Sub

    lunedì 6 ottobre 2008

    Configurazione Cisco SOHO 97 per NGI con 8 ip statici

    Avendo la necessità di configurare un router Cisco SOHO 97 per un'Adsl di NGI con 8 IP statici, mi sono fatto un giro per internet ma non ho trovato nulla che facesse al caso mio. Mi spiego:

    Degli 8 indirizzi pubblici statici assegnati, in realta solo 5 sono utilizzabili, in quanto il primo, il secondo e l'ultimo della subnet sono indirizzi di "servizio".

    La mia necessita era di riuscire a fare il NAT 1:1 degli indirizzi pubblici su indirizzi privati in modo che da permettere la gestione di quest'ultimi attraverso il mio server PFSense. Praticamente la struttura della rete è questa:

    Router <--> PFSense <--> Rete interna (MZ e DMZ)

    Praticamente, una persona dal "mondo" fa una richiesta all'indirizzo pubblico, il router lo passa al PFSense come indirizzo privato sull'interfaccia WAN del PFSense, il PFSense lo traduce in un indirizzo di un server sull'interfaccia LAN o DMZ.

    Siccome la configurazione del Router mi ha fatto "dannare" un po', la posto di seguito:


    no service pad
    service timestamps debug datetime msec
    service timestamps log datetime msec
    enable secret
    !
    hostname NomeDelRouter
    !
    boot-start-marker
    boot-end-marker
    !
    enable password PasswordDiEnable
    !
    no aaa new-model
    !
    resource policy
    !
    !
    !
    ip cef
    ip domain name ngi.it.
    ip name-server 88.149.128.12
    ip name-server 88.149.128.22
    !
    username UserAR password 0 PasswordAR
    !
    !
    !
    !
    interface Ethernet0
     ip address 192.168.0.254 255.255.255.0
     ip nat inside
    !
    interface ATM0
     no ip address
     ip nat outside
     no ip mroute-cache
     no atm ilmi-keepalive
     dsl operating-mode auto
     hold-queue 224 in
     pvc 8/35
      encapsulation aal5snap
      protocol ppp dialer
      dialer pool-member 1
     !
    !
    interface Dialer0
     ip address negotiated
     ip nat outside
     encapsulation ppp
     dialer pool 1
     dialer-group 1
     ppp pap sent-username UserADSL password 0 PassADSL
    !
    ip route 0.0.0.0 0.0.0.0 Dialer0
    no ip http server
    !
    ip nat inside source static 192.168.0.1 interface Dialer0
    ip nat inside source static 192.168.0.10 IpPubblico1
    ip nat inside source static 192.168.0.11 IpPubblico2
    ip nat inside source static 192.168.0.12 IpPubblico3
    ip nat inside source static 192.168.0.13 IpPubblico4
    ip nat inside source static 192.168.0.14 IpPubblico5
    !
    !
    control-plane
    !
    !
    line con 0
     no modem enable
    line aux 0
    line vty 0 4
     login local
    !
    scheduler max-task-time 5000
    end

    Dove UserAR e PasswordAR sono rispettivamente il nome utente e la password per l'accesso da remoto (console o telnet), UserADSL e PassADSL sono utente e password della connessione.
    192.168.0.254 è l'indirizzo di rete del router.
    192.168.0.1 è l'indirizzo dell'interfaccia WAN del PFSense.
    192.168.0.10-14 sono gli indirizzi su cui natto gli indirizzi pubblici.

    Degno di nota il fatto che NGI, come si vede, non assegna un indirizzo ip statico di punto-punto (interfaccia Dialer0 del router) ma lo da via DHCP, anche se in realtà l'indirizzo assegnato appunto via DHCP sarà sempre il II nel pool di indirizzi assegnato.

    venerdì 26 settembre 2008

    Scompattare con SharpZipLib e VB.net un file zip con sottocartelle

    Routine di scompattazione di un file Zip con l'utilizzo della dll rilasciata da ICSharpCode (IC#Code), open source, che si chiama SharpZipLib (#ZipLib) scaricabile liberamente QUI


    Imports ICSharpCode.SharpZipLib.Zip
    ......
    If File.Exists(fileName) Then

        destPath = fileName.Substring(0, fileName.Length - 4)

        If Not Directory.Exists(destPath) Then
            Directory.CreateDirectory(destPath)
        Else
            For Each s As String In Directory.GetFiles(destPath)
                File.Delete(s)
            Next
        End If

        Dim inStream As New ZipInputStream(File.OpenRead(fileName))
        Dim outStream As FileStream
        Dim entry As ZipEntry
        Dim buff(2047) As Byte
        Dim bytes As Integer

        Do While True
            Try
                entry = inStream.GetNextEntry()
                If entry Is Nothing Then
                    Exit Do
                End If

                If entry.Name.Last() = "/" Then
                    Directory.CreateDirectory(destPath & "\" & _
                    entry.Name.Replace("/", "\"))
                Else
                    Try
                        outStream = File.Create(destPath & _
                        "\" & entry.Name, 2048)
                        Do While True
                            bytes = inStream.Read(buff, 0, 2048)
                            If bytes = 0 Then
                                Exit Do
                            End If
                            outStream.Write(buff, 0, bytes)
                        Loop
                        outStream.Close()
                    Catch
                    End Try
                End If
            Catch
    ex As ZipException
                rtn += ex.Message & vbCrLf
            End Try
        Loop

        inStream.Close()
    Else
        rtn = "File '" & fileName & "' non trovato."
    End If

    giovedì 18 settembre 2008

    Copia ricorsiva di File e Cartelle in VB.Net

    Sembra banale, ma a volte la semplice copia dei file e delle sottodirectory contenute in una cartella può mettere in crisi un programmatore, proprio per la sua banalità.
    Proprio per evitare questo, posto un esempio di copia ricorsiva.

    Private Sub Copia(ByVal PathOrigine As String, _
                ByVal PathDestinazione As String)
        Dim Files() As String

        If PathDestinazione.Chars(PathDestinazione.Length - 1) <>
                Path.DirectorySeparatorChar Then
            PathDestinazione += Path.DirectorySeparatorChar
        End If

        If Not Directory.Exists(PathDestinazione) Then
            Directory.CreateDirectory(PathDestinazione)
        End If

        Files = Directory.GetFileSystemEntries(PathOrigine)

        Dim Elemento As String

        For Each Elemento In Files
            'Sotto cartelle
            If Directory.Exists(Elemento) Then
                Copia(Elemento, PathDestinazione +
                    Path.GetFileName(Elemento))
                ' File nella cartella
            Else
                File.Copy(Elemento, PathDestinazione +
                    Path.GetFileName(Elemento), True)
            End If
        Next Elemento
    End Sub

    martedì 26 agosto 2008

    Assegnare variabile da Select con SQLServer

    A volte può essere utile salvare il risultato di una Select in una variabile, magari per poterla riutilizzare all'interno di un'altra Select senza dover annidare varie query.
    Il comando per fare ciò è molto semplice:

    DECLARE @variabile AS tipovariabile

    SELECT @variabile = Campo FROM Tabella WHERE Condizione

    Si devono solo seguire alcuni accorgimenti:
    • tipovariabile deve essere, ovviamente, dello stesso tipo dei dati contenuti in Campo
    • nel caso in cui la query restituisca più di una riga, la variabile conterrà il valore dell'ultima riga (questo è molto importante, in quanto se ad esempio si trattasse di date e volessimo memorizzare nella variabile la data più recente, effettuando un "ORDER BY Data DESC" otterremo l'effetto contrario in quanto memorizzando l'ultima riga ci troveremmo in realtà la data piu vecchia)
    • non si può usare la clausola TOP

    Update da Select con Sql Server

    Supponiamo di trovarci in questa situazione: dobbiamo aggiornare dei record in database e come dati di partenza abbiamo il risultato di una query. Le soluzioni sono 2: o modifichiamo la tabella a mano (il che con migliaia di record da modificare potrebbe essere un po fastidioso) oppure possiamo usare uno scriptino T-Sql che fa esattamente quello che ci serve (a patto però di avere un campo nella query che ci permetta di effettuare un join con la tabella da aggiornare).
    Il codice è il seguente:

    UPDATE T
        SET T.Campo1a = Q.Campo2a,
        T.Campo1b = Q.Campo2b
    FROM
        (SELECT CampoID, Campo2a, Campo2b
        FROM Tabella WHERE Condizione) Q
    INNER JOIN TabellaDaModificare T
        ON T.CampoID = Q.CampoID


    Dove T è l'alias utilizzato per la tabella da modificare e Q è l'alias della Select.
    Il Join farà in modo che i campi si aggiornino solo dovo apportuno (praticamente è come se gli facessimo fare un "Update ... Where")

    giovedì 14 agosto 2008

    Backup TrixBox

    Mondoarchive è una soluzione di backup per sistemi *nix che crea file .iso con dimensioni di cd oppure dvd contenenti l’intera immagine del disco (un po’ come ghost sotto Windows). È una soluzione estremamente potente in quanto, tra le altre cose, una volta masterizzate le immagini sono bootabili ed autorestoranti. In questo modo, anche se ad esempio il disco del vostro server/pc si rompe, è possibile ripristinare l’installazione senza dover reinstallare tutto.
    Inoltre, lo script di avvio/configurazione permette di scegliere se creare i file di immagine su disco, su chiavette usb, su share samba (cartelle di rete) oppure su ftp.
    Per qualsiasi informazione aggiuntiva, visitate il sito dei realizzatori: http://www.mondorescue.org/
    La procedura descritta qui sotto è ottimizzata per effettuare i backup di Trixbox versione 2.4 e 2.6 e di sistemi Asterisk.

    Installazione
    Come utente root, eseguire i comandi:
    cd ~
    wget http://www.dbtek.it/Repository/install-mondo.tgz
    (o su http://www.astusers.org/install-mondo.tgz)
    tar -xzvf install-mondo.tgz
    chmod +x install-mondo.sh
    ./install-mondo.sh

    Lo script install-mondo.sh scarica tutte le dipendenze, installa mondo backup e crea una configurazione personalizzata per trixbox.
    Finita l’installazione è necessario riavviare il sistema.

    Poi bisogna editare il file /etc/cron.weekly/mondobackup.cron per attivare le opzioni di backup desiderate e configurare il programma. Tutte le istruzioni necessarie sono contenute direttamente all’interno del file sotto forma di commenti (in lingua inglese).

    Per testare il funzionamento della procedura eseguire /etc/cron.weekly/mondobackup.cron

    ATTENZIONE: se si verificano degli errori sul mount di drive samba (condivisioni di rete su Microsoft) e il vostri username o password per la condivisione utilizzano caratteri diversi dalle semplici lettere e numeri dovete inserire prima e dopo la stringa un apice ( ‘ )


    Ripristino di un backup
    Per ripristinare un backup effettuato con Mondo, si possono scegliere diverse alternative:

    Nuke (formatta il disco e ripristina tutto, automaticamente)
    Interactive
    Expert

    Inoltre è possibile provare a ripristinare solo il bootloader (se non si è perso il disco):
    • Far il boot dal CD/DVD di backup e scegliere Expert Mode
    • digitare: mondorestore --mbr
    • scegliere l’opzione 28 e poi
    bash# mount-me
    bash# chroot /mnt/RESTORING
    bash# lilo oppure grub-install ’(hd0)’
    bash# exit
    bash# unmount-me

    Nuke Restore
    Come già detto, questa opzione sovrascrive completamente il disco fisso del sistema, ripristinando automaticamente il backup

    • Fare il boot dal primo CD/DVD di backup
    • Scegliere RESTORE
    • Quando richiesto, inserire i CD/DVD seguenti (se presenti)
    • Controllare che non ci siano errori

    Se si verifica qualche errore, è possible controllare il file /tmp/mondorestore.log.

    Se si vuole vedere passo passo cosa sta facendo il programma, basta premere e per analizzare “on-the-fly” il log.

    Interactive Restore
    L’Interactive Mode permette di ripristinare un sottoinsieme di dati dal backup, e non l’intero sistema, oppure si può utilizzare per ripristinare tutti i file ma senza dover formattare il disco.

    Il ripristino interattivo fornisce l’ “Editing mountlist screen” che permette di impostare diverse geometrie del disco. Per spostarsi tra le partizioni utilizzare le frecce su e giu. Per spostarsi tra i bottoni, invece utilizzare le frecce destra e sinistra.

    Per ripristinare solo una parte dei file, la procedura da seguire è la seguente:
    • Fare il boot dal primo CD/DVD di backup
    • Digitare interactive
    • Rispondere alle domande poste:
    Do you want to partition your devices? no
    Do you want to format them? no
    Do you want to restore everything? no
    Do you want to restore something? yes
    Which path do you want to restore? /mydata (ad esempio)
    Do you want to run LILO to setup your boot sectors? Yes

    Expert Restore
    Per effettuare un restore manuale:
    • Fare il boot dal primo CD/DVD di backup
    • Digitare expert
    • Digitare mondorestore

    Ora dovreste seguire le istruzioni a video per modificare a piacimento il sistema e ripristinare manualmente i file.