wtorek, 5 marca 2013

ActiveSync - list of devices synced in last 14 days.

If somebody would like to get a list of devices that are synced with Exchange here is a command, could be helpful for someone.

Get-Mailbox -ResultSize Unlimited -OrganizationalUnit 'OU=<YOUR_OU>,DC=<YOUR_DOMAIN>,DC=com' | foreach-object { Get-ActiveSyncDeviceStatistics -mailbox $_.alias |  where {$_.Lastsuccesssync -gt (Get-Date).AddDays("-14")} | foreach-object {$_.Identity} } |  export-csv c:\ActiveSyncList.csv -encoding unicode

It lists devices that have been synced during last 14 days, because sometimes people have old deviced that visible in Exchange.

poniedziałek, 4 marca 2013

TSM - monitoring DB backup state with ZABBIX.

Hi Guys,

If you would like to monitor your TSM server with ZABBIX for ex., here are some useful selects to TSM database. Below are user parameters that has to be put in zabbix_agentd.conf:

UserParameter=Scratch,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 1"
UserParameter=Buffhit,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 2"
UserParameter=FreeSpaceDb,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 3"
UserParameter=FreeSpaceLog,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 4"
UserParameter=SchedulesMissed,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 5"
UserParameter=SchedulesFailed,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 6"
UserParameter=PathsOffline,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 7"
UserParameter=HighSGTUtilization,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 8"
UserParameter=RwErrors,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 9"
UserParameter=UnVolumes,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 10"
UserParameter=UnHosts,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 11"
UserParameter=Scratch_BCKP,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 12"
UserParameter=Scratch_OFF,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 13"
UserParameter=TsmBackupStatus,%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe /nologo "C:\zabbix\TsmInformation.ps1 14"
And here is a powershell script that retrieves those pieces of information:
param($select)

switch ($select) 
    { 
        1 {$select = "select count(*) as Scratch from libvolumes where status='Scratch'"} 
        2 {$select = "select buff_hit_ratio from db"} 
        3 {$select = "select cast((free_space_mb/1024) as decimal(8,2)) from db"}
        4 {$select = "select free_space_mb/1024 from log"} 
        5 {$select = "select count(*) from events where status='Missed'"}
        6 {$select = "select count(*) from events where status='Failed'"}
        7 {$select = "select count(*) from paths where NOT online='YES'"}
        8 {$select = "select count(*) from stgpools where pct_utilized>95"}
        9 {$select = "select count(*) from volumes where read_errors>0 or write_errors>0"}
       10 {$select = "select count(*) from volumes where access='UNAVAILABLE'"}
       11 {$select = "select count(*) from nodes where node_name NOT IN (select node_name from associations)"} 
       12 {$select = "select count(*) as Scratch from libvolumes where status='Scratch' and library_name='TS3310_BCKP'"}
       13 {$select = "select count(*) as Scratch from libvolumes where status='Scratch' and library_name='TS3310_OFF'"}
       14 {$select = "select last_backup_date from DB"}
        default {"BRAK PARAMETRÓW"}
    }

$a = (& C:\Progra~1\Tivoli\TSM\baclient\dsmadmc.exe -optfile=C:\Progra~1\Tivoli\TSM\baclient\dsm.opt -id=Admin -pa=<PUT_HERE_YOUR_TSM_PASSWORD> -display=list -dataonly=yes "$select")
$b = $a | Select-Object -first 1
$c = $b.split(":")
$d = $c[1].Substring(1)
#$d = $d.replace(".",",")
if ( $d -match " ") {
    $e = $d.split(" ")
    $f = $e[0].Substring(0)
    $d = Get-Date
    $data = (get-date).ToString("yyyy-MM-dd")
    $data2 = (get-date).AddDays(-1).ToString("yyyy-MM-dd")
if (($f -eq $data) -or (($f -eq $data2) -and ($d.Hour -lt "10")) ){
    "BACKUP UP TO DATE"
    } else { $f }
} else { $d }

SCCM 2007 to 2012 migration scripts for colletions and packages.

I am still planning to write the whole great and shiny article about my operation of SCCM 2007 to 2012 migration :], but firstly I would like to publish couple of scripts that were very helpful for me.
1. The need of changing the "parent collection" for some collections came because we plan to use SCCM for managing the servers also, but we want to limit the ability of managing them to Administrators only. We do not want helpdesk admins - that are creating packages - to deploy accidentially package on any of them, or simply to have any access to them.

New SCCM has great ability - oh my God finally!!! - to restrict permissions on particular collections. So I left collection "All system" in the root "Device collections", later I have created collection "All Workstations Helpdesk", with limitation to "All systems" with proper query based on OU's that is limiting it to just workstations, and put it in the folder to which I gave permissions for my helpdesk admis.

That worked great! Helpdesk Admins didn't have any ability to change "All Workstations Helpdesk" membership, because they didn't have permissions for (and accually didn't even saw) "All systems" collection. And they could buil new collections based on that collection.

Old collections had to be migrated - there were advertisements that was deployed on them, my colleagues made them to make some reports for managers, or just for themselves.

The problem was, all old collections had "parent collection" set to "All systems". Standing in front on 400 collections I made up a decision.

- Fuck, i need a script...

So here it is:

#---------------------
# Here I am setting up date just for logging purposes.

$date = Get-Date
$data = Get-Date –f "yyyy-MM-dd_HH";
$log_file = "c:\SCCM_Collections_Migration_$data.log"

$All_Collections = (gc c:\Collection_Name_List.txt)

#---------------------

Foreach ($kolekcja in $All_Collections) {
$Collection = $kolekcja
if ($Collection -eq "All Systems")
{

#---------------------
# We take the name of the current parent collection for collection that is beind processed - just in case we want to revert changes (useful :))

$Old_Collection = (Get-WmiObject -Namespace "root\SMS\Site_WRO" -Class SMS_Collection -Filter "Name='$Collection'")
$Old_Collection.LimitToCollectionName
$Stara_kol = $Old_Collection.LimitToCollectionName
#---------------------

#---------------------
# Here make the change of the collection, we need to know the name of the new collection AND it's ID!

$CollectionQuery = Get-WmiObject -Namespace "root\SMS\Site_WRO" -Class SMS_Collection -Filter "Name='$Collection'"
$CollectionQuery.LimitToCollectionName = "All Workstations"
$CollectionQuery.LimitToCollectionID = "WRO0000B"
$CollectionQuery.Put()
#---------------------

#---------------------
#Just for logging pusposes - taking the new collection name - to be sure it has changed

$New_Collection = (Get-WmiObject -Namespace "root\SMS\Site_WRO" -Class SMS_Collection -Filter "Name='$Collection'")
$New_Collection.LimitToCollectionName
$Nowa_kol = $New_Collection.LimitToCollectionName
#---------------------

#---------------------
# Here we are writing output to the file, if the names od ids are not the same - the error is being writed to the file. The error logging is maybe not so sophisticated but is enought :)

if (($Old_Collection.LimitToCollectionName -ne $New_Collection.LimitToCollectionName) -and ($Old_Collection.LimitToCollectionID -ne $New_Collection.LimitToCollectionID)) {
$Data_row = "Success, for collection "+$Collection+" old limiting collection "+$Stara_kol+" has been changed to "+$Nowa_kol
Add-Content $log_file "$Data_row"
} else {
$Data_row = "ERROR The problem occured when changing the parent collection!"
Add-Content $log_file "$Data_row"
}
#---------------------
}

}


The problem I met was migration of packages. Before running the migration I didn't realize the problem, hance I was really fucking astonished when after migration the packages/advertisements I saw in distmgr.log flood of errors saying that SCCM cannot find appropriate path for sources.

I was like:














Apparently I have missed one fundamental thing - migration taks do not migrate sources and do not change the path on it.

Well... shit :)

I have moved the sources but I was left with almoust hundred of packages in which I had to change path to sources. Additionally I have noticed that some packages had relative path, and some not.
Here is a script for that, :
 
$CollectionQuery = Get-WmiObject -Namespace "root\SMS\Site_WRO" -Class SMS_Package
Foreach ($Pakiet in $CollectionQuery) {
$Pakiet.name
$Pakiet.PkgSourcePath
$Sciezka = $Pakiet.PkgSourcePath
$Poprawka = $Sciezka.Replace("D:\<LOCAL_PATH.","\\<NEW_SCCM_SERVER>\E$").Replace("\\<OLD_SCCM_SERVER>\d$","\\<NEW_SCCM_SERVER>\E$")
$Pakiet.PkgSourcePath = $Poprawka
$Pakiet.PkgSourcePath
$Pakiet.Put()
}


niedziela, 3 marca 2013

Listing permissions for Sharepoint 2010 - including information about inheritable permissions lists/libraries and files

I am about to describe my struggling with SCCM 2007 to 2012 upgrade, but just before that I would like to share with you guys a script I was dreaming to have time to write to.

I am talking about script that is listing permissions for sharepoint and all libraries and files that don't inherit permissions.

It was slightly a horrible nightmare for me to list permissions for the web application - there was a time, where users had power to grant permissions for folders and files. After a couple of years there was an idea from the managment - let's take back those permissions and put everythign in User Rights Management system...

First thought:
- F*#k
Second - much the same. Finally I had some time and written a script that lets me to specify precisely on what file in what library who the hell has permissions :D

Here it is:

$url = "http://<WEB_APPLICATION_NAME>"
$site = Get-SPWeb ($url)
$pliki = @()

foreach ($web in $site.Site.AllWebs)
{

# if ($web.Url.StartsWith($url)) { # Uncomment for listing whe whole web application

  if ($web.Url -match "http://<WEB_APPLICATION_NAME>/<SOME_FOLDER>") { #Uncomment to list just one particular site

#-----------

    $host.ui.RawUI.ForegroundColor = “Green”;
    Write-Host ("PErmissions for website " + $web.Name + " ,Url: " + $web.Url)
    $lists = $web.Lists
    Write-Host "Website contains the content libraries:"
    $host.ui.RawUI.ForegroundColor = “white”;
    foreach ($list in $lists) {

#-----------
# (START) Getting the files with non heritable permissions
#-----------
        foreach ($ll in $list.items){
            if ($ll.HasUniqueRoleAssignments -match "True"){
            $e = $ll.url
               foreach ($upr_f in $ll.RoleAssignments){
               $f = $upr_f.member.name
               $g = $upr_f.RoleDefinitionBindings | foreach {$_.name}
               $paczka = "$e,$f,$g"
               $pliki += $paczka
               }        
            }
        }
#-----------
# (END) Getting the files with non heritable permissions
#-----------

#-----------
# (START) Getting the list/libraries with inheritable permissions
#-----------

    $l = $list.folders
    foreach ($upr in $l){

#-----------
#   if ($upr.name -match "Systemy - admini"){ #Uncoment if you would like to list particular list/library, do not forget
#   to uncommenct the bracket below
#-----------
    $a= $upr.Url
    $b = $upr.HasUniqueRoleAssignments
       
        if ($b -eq "True"){
        $host.ui.RawUI.ForegroundColor = “green”;
        Write-Host "The list/library with unique permissions:"
        $host.ui.RawUI.ForegroundColor = “yellow”;
        }
       
        foreach ($u in $upr.RoleAssignments){
        $c = $u.member.name
        $d = $u.RoleDefinitionBindings | foreach {$_.name}
        Write-Host "$a, $c, $d"
        }
   
        if ($pliki) {
        $host.ui.RawUI.ForegroundColor = “Green”;
        Write-Host "Files with unique permissions"
        $host.ui.RawUI.ForegroundColor = “yellow”;
        $pliki}

    $pliki = @()
    $host.ui.RawUI.ForegroundColor = “Green”;
    Write-host "#-------------"
    $host.ui.RawUI.ForegroundColor = “white”;
#----------
#   } Bracket for "IF" specifying list/library
#----------
   }

#-----------
# (END) Getting the list/libraries with inheritable permissions
#-----------

  }
 }
}

piątek, 1 marca 2013

Reports migration form SCCM 2007 to SCCM 2012

Recenty I had some troubles during reports migration from SCCM 2007 to SCCM 2012.

By the way - I am going to write a quite big article about my struggling with SCCM upgrade - I hope the migration nightmare will ends this month :)

So as I was saying, after migrating reports I was received such an error:

Microsoft.Reporting.WinForms.ReportServerException
The report server cannot process the report or shared dataset. The shared data source 'AutoGen__5C6358F2_4BB6_4a1b_A16E_8D96795D8602_' for the report server or SharePoint site is not valid. Browse to the server or site and select a shared data source. (rsInvalidDataSourceReference)


Stack Trace:
   at Microsoft.Reporting.WinForms.ServerReportSoapProxy.OnSoapException(SoapException e)
   at Microsoft.Reporting.WinForms.Internal.Soap.ReportingServices2005.Execution.RSExecutionConnection.ProxyMethodInvocation.Execute[TReturn](RSExecutionConnection connection, ProxyMethod`1 initialMethod, ProxyMethod`1 retryMethod)
   at Microsoft.Reporting.WinForms.Internal.Soap.ReportingServices2005.Execution.RSExecutionConnection.LoadReport(String Report, String HistoryID)
   at Microsoft.Reporting.WinForms.ServerReport.EnsureExecutionSession()
   at Microsoft.Reporting.WinForms.ServerReport.SetParameters(IEnumerable`1 parameters)
   at Microsoft.ConfigurationManagement.AdminConsole.SrsReporting.ReportViewerWindowsForms.SetParameterValues_DoWork(Object sender, DoWorkEventArgs e)


I couldn't find what is the issue, I was doing it with the ReportSync tool I have read about here:

http://blog.coretech.dk/kea/migrate-reports-from-sccm-2007-to-sccm-2012-sp1/

But there was nothing about that error :/ so I was searching further and found that great article, it is quite similar buuut... it has explanation of how to get rid of thta error :)

http://www.mydreampage.net/

Blog is written as a one page so you have to search by "Migrate the SCCM 2007 reports to SCCM 2012" header.

In case the website was no longer available - you have to do the fallowing after migration:

1. Go to to website http://<your_sqlreporting_server>/reports
2. Go to report that you have problem with
3. Click on it - so you will have error on the screen
4. Click on the report name on the top of the page (for ex. if your path to the report on the top looks like "Home > ConfigMgr_WRO > Asset Intelligence > Hardware 01A - Summary of computers in a specific collection" <- click on the bolded name) - it will lead you to the properties of the report.
5. Change the datasource of the report - don't worry if the "test connecion" won't work.
6. Go to report and run it :) it should be all fine

Unfortunatelly I have had about hundreds of reports to correct the data source, figuring out the script was the priority :) I have found a great script on that website:

http://ask.sqlservercentral.com/questions/86369/change-datasource-of-ssrs-report-with-powershell.html?sort=oldest

For me it was like:

$newDataSourcePath = "/ConfigMgr_WRO/{5C6358F2-4BB6-4a1b-A16E-8D96795D8602}";
$newDataSourceName = "AutoGen__5C6358F2_4BB6_4a1b_A16E_8D96795D8602_";
$SiteCode = "WRO"
$serverName = "WROSCCM"
$reportFolder = "/ConfigMgr_WRO/ConfigMgr_OldSite";

$ssrs = New-WebServiceProxy -uri http://$serverName/ReportServer/ReportService2005.asmx?WSDL -UseDefaultCredential

$reports = $ssrs.ListChildren($reportFolder, $True)

$reports | ForEach-Object {
  
    $reportPath = $_.path

   $dataSources = $ssrs.GetItemDataSources($reportPath)
    $dataSources | ForEach-Object {
      
        $proxyNamespace = $_.GetType().Namespace
        $myDataSource = New-Object ("$proxyNamespace.DataSource")
        $myDataSource.Name = $newDataSourceName
        $myDataSource.Item = New-Object ("$proxyNamespace.DataSourceReference")
        $myDataSource.Item.Reference = $newDataSourcePath
        $_.item = $myDataSource.Item
        $ssrs.SetItemDataSources($reportPath, $_)
        Write-Host "Report's DataSource Reference ($($_.Name)): $($_.Item.Reference)";
        }

}



The script will modify all reports in the "$reportFolder" and it's subfolders! Isn't it great!?