Lync commands in powershell

imagesEd ecco a grande richiesta come gestire Lync con powershell. Ho notato che e’ veramente difficile trovare informazioni ed esempi relativi al’utilizzo dei comandi Lync in poweshell.Prima di tutto ecco il link per partire: La guida technet ai comandi Lync. Adesso possiamo iniziare a vedere un po’ di codice:

Ricordiamoci di importare il modulo di lync per poter utilizzare i suoi comandi:

Import-Module 'C:\Program Files\Common Files\Microsoft Lync Server 2013\Modules\Lync\Lync.psd1'

Se volessimo avere la lista di tutti gli utenti ecco il codice:

$users = Get-CsUser -Filter {RegistrarPool -eq "lync.server"} | select sipaddress
foreach ($user in $users)
{
$usermail = $user.Split(":")
Write-Host $usermail
}

In questo modo abbiamo chiesto di avere una lista di tutte le mail registrate su lync e di stamparle a video. Per avere tutti i dati dell’utente bastera’
eliminare la select finale.

Un’altro comando inderessante e’ Export-CsUserData: la sua descrizione e’:
“Exports user data in a format that can be imported into Microsoft Exchange Server 2013. The data will be exported as a .ZIP file containing a pair of XML documents. This cmdlet was introduced in Lync Server 2013.”

Ed ecco il codice:

Export-CsUserData -FileName $zipfile –UserFilter $ExportEmail -PoolFqdn "lync.server"

L’ultimo comando che ho utilizzato e’ Update-CsUserData. Questo serve per aggiornare i contatti di ogni user:

Update-CsUserData -FileName $zipFile -Confirm:$False

Notare l’uso dell’attributo -Confirm:$False: Questo mi forza la conferma del comando senza visualizzazione di un messaggio di conferma. E’ molto utile
vogliamo inserire il comando in uno script automatico.

E finalmente ecco il codice completo, naturalmente sempre nel mio repository GitHub: Le funzionalita’ di questo script sono le seguenti:

  • Esportazione della lista contatti
  • Unzip dell’esportazione
  • Modifica del file xml generato da Lync
  • Check e validazione delle mail
  • Zip delle modifiche
  • Update lista contatti

Questo viene eseguito per ogni utente di Lync, E’ molto utile durante la migrazione di Lync 2010 a Lync 2013. Di seguito il suo utilizzo:

LyncContacts.ps1 –UserEmail all –ExportEmail email@email.it In questo modo migriamo tutti gli utenti e per ogni utente usiamo la lista contatti ExportEmail come default

LyncContacts.ps1 –UserEmail email@email.com –ExportEmail email@email.it In questo caso migriamo solo un user e utilizziamo la ExportMail come default dei contatti

Spero di essere stato utile a qualcuno.

PowerShell

imagesSono due giorni che sto “smanettando” con powershell: Sto creando una poweshell per importare i contatti Lync (Migrazione da Lync 2010 a Lync2013). Per risolvere il problema ho dovuto crearmi una lista di utenti lync e ciclare su ogni utente. Per ognuno ho dovuto creare un file zip, modificare un file xml e poi eseguire un altro comando della powershell di lync.

Dato che non sono molto pratico di powershell ho cercato un po’ su internet e alla fine sono riuscito a creare tutto quello che mi serviva, senza importare nessuna libreria esterna ma utilizzando la potenza di powershell. Vediamo come ho risolto il tutto:
Per iniziare mi sono creato dei metodi base per la gestione degli zip, delle cartelle e del file xml:
In questo post vedremo questo. Magari in futuro vi faro’ vedere i comandi lync… 🙂

Prima di tutto ho creato delle cartelle temporanee per poter lavorare in tranquillita’:

#Tmp dir
$folderTmp = "C:\TmpLync\"
$folderTmpContact = "C:\TmpLync\Contacts"
#********************************************************************************************************************************************
#Start TMP FOLDER
#********************************************************************************************************************************************
#Clean and create all tmp dir
if (!(Test-Path $folderTmp)) {
# create it
[void](new-item $folderTmp -itemType directory)
}
if (!(Test-Path $folderTmpContact)) {
# create it
[void](new-item $folderTmpContact -itemType directory)
}

Poi ho creato le funzioni per zippare ed unzippare cartelle

function UnZipMe($zipfilename,$destination)
{
   $shellApplication = new-object -com shell.application
   $zipPackage = $shellApplication.NameSpace($zipfilename)
   $destinationFolder = $shellApplication.NameSpace($destination)
	# CopyHere vOptions Flag # 4 - Do not display a progress dialog box.
	# 16 - Respond with "Yes to All" for any dialog box that is displayed.
	$destinationFolder.CopyHere($zipPackage.Items(),20)
}

function ZipMe($srcdir,$ZipFileName,$zipFilepath )
{
		$zipFile = "$zipFilepath$zipFilename"
		#Prepare zip file
		if(-not (test-path($zipFile))) {
		    set-content $zipFile ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
		    (dir $zipFile).IsReadOnly = $false
		}

		$shellApplication = new-object -com shell.application
		$zipPackage = $shellApplication.NameSpace($zipFile)
		$files = Get-ChildItem -Path $srcdir | where{! $_.PSIsContainer}

		foreach($file in $files) {
		    $zipPackage.CopyHere($file.FullName)
			#using this method, sometimes files can be 'skipped'
			#this 'while' loop checks each file is added before moving to the next
		    while($zipPackage.Items().Item($file.name) -eq $null){
		        Start-sleep -seconds 1
		    }
		}
}

L’utilizzo di queste due funzioni e’ semplicissimo:
Per unzippare:

$zipFilename = "contacts.zip"
$a = gci -Path $folderTmpContact -Filter $zipFilename
foreach($file in $a)
{
    Write-Host "Processing - $file" UnZipMe –zipfilename
    UnZipMe –zipfilename $file.FullName -destination $file.DirectoryName
}

Per zippare:

$srcdir = $folderTmpContact
$zipFilepath = $folderTmp
ZipMe -srcdir $srcdir -zipFileName $ZipFileName -zipFilePath $zipFilepath

La parte piu’ complessa e’ stata la gestione e la modifica del file XML: Ho provato ad utilizzare i comandi standard per leggere un file xml:

$xml = New-Object XML
$xml = [xml](get-content "c:\test\DocItemSet.xml")
$email = $xml.DocItemSet.DocItem[0].name

Ma la stringa da ricercare non aveva logica e il file xml poteva cambiare. Alla fine ho deciso di utilizzare una semplice ricerca e modifica:

$original_file = "c:\test\DocItemSet.xml"
$destination_file =  "c:\test\DocItemSet.xml.new"
(Get-Content $original_file) | Foreach-Object {
    $_ -replace $email, 'something1aa'
    } | Set-Content $destination_file

In questo modo ricerco, modifico e faccio anche un backup del file.
Per lavorare e per debuggare poweshell ho utilizzato PowerGUI mentre per un ottimo punto di partenza per powershell consiglio questi link:

http://powershell.com/
http://powershell.it/Comandi/v1.0/Get-Content.aspx
http://powershell.it/Tutorial/Introduzione-a-PowerShell.aspx

NB: Se abbiamo il seguente errore File xyz.ps1 cannot be loaded because the execution of scripts is disabled on this system. Please see “get-help about_signing” for more details. Esesguiamo la console powershell ed eseguiamo il seguente comando:
Set-ExecutionPolicy Unrestricted -Force
Set-ExecutionPolicy RemoteSigned -Force

Spero di essere stato utile…
Buon divertimento a tutti!!!