Wednesday, December 16, 2015

SCCM 2012:: Powershell:: Script to get the SCCM server log files and their location details and export it to an HTML report

This script will give you the list of log files for each components installed on each server on your SCCM infrastructure.

Script can be run from CAS server.

Add your CAS Servername and CAS site code to the script.

An HTML file will be generated on your desktop which shows you the log file path and link to directly open the log file from the machine from where you are running the script.

 Powershell remoting should be enabled on all servers.

The output would be similar to the below screenshot.


  
Note: This does not cover the SMSDPProv.log and smsdpusage.log

Tuesday, August 11, 2015

SCCM 2012:Powershell: Find the name of the collections in which the device is member or listed.

Here is a script to find collection names which a device is member of .
We will collect all collection names and then we will run the command get-cmdevice on each collection to check if the device is member of that collection. Collection name will be returned if the device is member of the collection.


#Get all collections you can enter collection name filters if needed ex: -name "*windows 7*"
$collections=Get-CMDeviceCollection | select Name
# Import the CSV which has the list of machines. Heading of CSV should be HostName
#or you can use a text file and use the command get-content
$devices=Import-Csv -Path $env:USERPROFILE\desktop\Device_List1.csv

foreach($device in $devices)
{
$hostname=$device.HostName
$break=$false
foreach($collection in $collections)
{
   $colName=$collection.Name
   $colObj=Get-CMDevice -CollectionName $colName -Name $hostname
   if($colObj -ne $null)
   {
    Write-Output "$hostname found in $colName"
    $break=$true;
   }
}
if(-not($break))
{
  Write-Host "$hostname not found in any collection"
}
}

Thursday, June 18, 2015

Initiate a machine policy or user policy on the client machine/members of a collection

Very useful command which can trigger the client machine policy/user policy action. Can be triggered for a device or a collection.

Whenever I deploy an application to a set of my test machines, I would trigger this action from the SCCM powershell console which would make the deployment available quickly on the machine.

Example: 

Invoke-CMClientNotification

 

Invoke-CMClientNotification -DeviceCollectionName "CollectionName" -NotificationType RequestMachinePolicyNow -Verbose 

Refer: https://technet.microsoft.com/en-us/library/dn472965%28v=sc.20%29.aspx



Friday, June 5, 2015

Powershell:SCCM2012:How to enable Binary Differential Replication or Delta Replication property of a package


Function enableDeltaReplication($SiteServer,$SiteCode,$Namespace,$pkgId)
{
    $USE_BINARY_DELTA_REP = "0x04000000" #Property of SMS_PackageBaseclass for Delta replication. Refer: https://msdn.microsoft.com/en-us/library/cc146062.aspx

    $myPackage = Get-WmiObject -Namespace $Namespace -ComputerName $SiteServer -Query "SELECT *  FROM SMS_PackageBaseclass Where PackageID = '${pkgId}'"
    $res=$myPackage.PkgFlags -bor $USE_BINARY_DELTA_REP
    $myPackage.PkgFlags=$res
    $myPackage.Put()

    $myPackage = Get-WmiObject -Namespace $Namespace -ComputerName $SiteServer -Query "SELECT *  FROM SMS_PackageBaseclass Where PackageID = '${pkgId}'"
    if($myPackage.PkgFlags -band $USE_BINARY_DELTA_REP) {return $true} Else {return $false}
}

# $pkgid = package id of the package to enable binary differential replication

#refer get-cmpackage to obtain package id.



$siteCode="SITE_CODE" #Your CAS site code$replRes=enableDeltaReplication "Your_CAS_ServerName" $siteCode "root\sms\site_$($SiteCode)" $pkgid

Write-Host "Binary replication result ${replRes}"







Friday, May 1, 2015

How to find which process has blocked a folder/file using process explorer.

How to find which process has blocked a folder/file using process explorer.


Tool required: Process explorer
Process explorer can be downloaded from http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
Open process explorer

Click on Find->Find handle or DLL

Or press Ctrl+F

Enter the full path of the file/folder which is locked.

Detail will be displayed.

Thursday, April 30, 2015

SCCM 2012: Powershell: Copy SCCM logs from client machine

Script to pull sccm logs from the client machine.
Need to enter the hostname/ip and local administrator password on the csv file.
Powershell version required 3.0
------------------------------------------------------
This script is provided as is and with no warranties, it's the sole responsibility of the user to ensure it is tested prior to running on prod environment. 

-----------------------------------------------------------------------------------------------


$basefolder="C:\SCCM_Troubleshooting\" #Local machine folder where logs will be copied to "machinename_log" folder
#remove space from hostname field from excel
$csvpath="C:\SCCM_Troubleshooting\hostnames.csv"

if (-not(Test-Path $csvpath))

{
write-host "Hostname file not found, please place the csv file with hostnames and passwords at $csvpath"
exit 0;
}


$list=Import-Csv -Path $csvpath

$list | ForEach-Object{


$machine=$_.Hostname;
$machine=$machine.trim();
#Write-Host $machine
#read-host "Pause"
$PWord = ConvertTo-SecureString –String $_.Password –AsPlainText -Force
$user="$machine`\administrator"

$Creds = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $User, $PWord

New-PSDrive -Name cli2 -PSProvider FileSystem -Root \\$machine\C$ -Credential $creds


mkdir "$basefolder$machine`_logs"

Copy-Item cli2:\Windows\CCM\logs\ "$basefolder$machine`_logs" -Recurse -Verbose

remove-psdrive cli2

}













-----------------------------------------------------------------

Powershell: ARS : How to get user details from AD using ARS script

I had a situation where I wanted to pull the following details from ARS which I could not find in SCCM.

I extracted a report from SCCM from which I got the AD username of users and I ran it against the AD using ARS script to fetch the details and get it in a CSV. Then I combined both excel files to get all details.
---------------------------------------------------------------------------------------------------------------------

#This program pulls user data from ARS.

#input is kept in csv file in following variable, title should be "UserName" , it contains the AD usernames of the users.

$source=".\users2.csv"

#Below file will have the exported user details

$outfile=".\UserDetails-Exported.csv"

$list=Import-Csv $source

$results = @()

$count=0;

#Write the header to outfile.

Write-Output "UserID,LastName,FirstName,Email,Location" | Out-File $outfile -Encoding utf8 -Append

$list | foreach{

$username=$_.UserName;

$count+=1;

if($username.length -gt 3)

{

  get-qaduser $username |  foreach{$lname=$_.lastname;$fname=$_.firstname;$email=$_.email;$uid=$_.samaccountname;$location=$_.l;  }

  write-host $count

  Write-Host "$uid,$lname,$fname,$email,$location"

  Write-Output "$uid,$lname,$fname,$email,$location" | Out-File $outfile -Encoding utf8 -Append

  $details = @{          

                UserID=$uid

                FirstName= $fname

                LastName= $lname

                Email=$email              

                Location=$location

            }                          

  $results += New-Object PSObject -Property $details

}

else

{

  $lname="No data found";

  $fname="No data found";

  $email="No data found";

  $uid="No data found";

  $location="No data found"

  $details = @{          

                UserID=$uid

                LastName= $lname              

                FirstName= $fname

                Email=$email              

                Location=$location

            }

Write-Output "$uid,$lname,$fname,$email,$location" | Out-File $outfile -Encoding utf8 -Append

}

}

SCCM 2012 : Powershell: Change collection refresh interval to 4 hours

How to change all collection refresh interval to 4 hours from one day.

Few weeks ago we had a requirement to change all our collections to refresh every 4 hours, which were set for one day. I found some information on the web and compiled it to following script which enabled us to change the refresh interval of collection.


Below scripts gets the collections which have the refresh interval of 1 day.

This script is provided as is and with no warranties, it's the sole responsibility of the user to ensure it is tested prior to running on prod environment. 
---------------------------------------------------------
#set your CAS server name

$casservername="the-cas-server-name"


#new refresh interval which we want to set

$Schedule = New-CMSchedule -RecurInterval Hours -RecurCount 4


#Get all collections which have the refresh interval matching one day, you can include a -name  *match-text* to get only a certain collections which have certain text in their name.

#ex: Get-CMDeviceCollection -name *visio* -> all collections containing visio in their name


$collections=Get-CMDeviceCollection  | select Name,RefreshSchedule,CollectionID  -ExpandProperty RefreshSchedule | ? {$_.DaySpan -eq 1}


foreach($collection in $collections)

{

$ThisCollectionID=$collection.CollectionID

write-host "Working on " $collection.Name

$collection.RefreshSchedule | %{write-host "Dayspan and hourspan "  $_.DaySpan $_.HourSpan}

#replace CAS with your CAS site ID.


$a = [wmi] "\\${casservername}\root\sms\site_CAS:SMS_Collection.CollectionID='$ThisCollectionID'"

$a.RefreshSchedule=$Schedule.psbase.ManagedObject

$a.put()

}




















Wednesday, April 29, 2015

Powershell: SCCM 2012 bulk package creation script

This script is intended for those who want to create multiple packages in sccm at once.
Please test the script and make necessary changes before you use it in production.
This script is provided as is and without any warranty. Author is not responsible for any damages which might be caused by running this script without making changes prior to running it.

No error handling and minimal validations done in the script.

-----------------------------------------------------------------------------
#author lanabhat@gmail.com

#This script creates packages one by one from the details given in the CSV file,also creates programs, creates the collection.


#Package creation script, will create a package from given parameters, creates programs, creates the collection


#csv file header Package_RAW.csv

#SharePath,MsiPath,PackageName,PackageDescription,Manufacturer,Version,Lang,InstallCMD,UninstalllCMD,SpaceMB,SilentInstallCMD,CollectionName #note sometimes excel removes .0 etc ex 1.0 becomes 1

#If you are using an MSi following fields are not required PackageName,PackageDescription,Manufacturer,Version,Lang


#Run the CreateCollectionNSetDeployment.ps1 once the binary replication is enabled and package is distributed to DPs.



$list=Import-Csv $env:userprofile\desktop\Package_RAW.csv


$list | foreach{

$msipath=$_.MsiPath;

$msipackage=$false;


if($msipath -ne "")

{

$msipackage=$true

}

else

{

  $msipackage=$false

}

$pkgSrvShr=$_.SharePath; #ex: "\\myshare\software\Microsoft\Visio\VisioPro2013"

$name=$_.PackageName; #"Visio 2013 Pro"

$description=$_.PackageDescription; #"Visio 2013 Pro"

$manufacturer=$_.Manufacturer; #"Microsoft"

$ver=$_.Version;  #"2013"

$lng=$_.Lang;#"English"

$installcmdline=$_.InstallCMD;#"Install.vbs"

$SilentInstallCMDline=$_.SilentInstallCMD;

$uincommandline=$_.UninstalllCMD;#"Uninstall.vbs"

$space=$_.SpaceMB;#"450"


$lmtClctn ="CAS00001"

$clctnName=$_.CollectionName;

$rfrshScd=New-CMSchedule -RecurInterval Hours -RecurCount 4


#This is the standard query used to get the machines which are part of a ARS group. ARS group is $clctnName        

$qStmt="select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.SystemGroupName = 'DOMAIN\\"+$clctnName+"'"

    

#This is in pipeline to copy the package to server.

#Copy-Item -Path $pkgFileSrc -Destination $pkgSrvShr -Recurse



if($msipackage -eq $false) #If MsiPath is not entered in the excel, package is considered as non definition package.

{

$mypackage=New-CMPackage -Name $name -Description $description  -Language $lng -Manufacturer $manufacturer -Path $pkgSrvShr -Version $ver

}

else #below code for package from definition

{


$mypackage=New-CMPackage -FromDefinition -PackagePath $msipath -SourceFileType AlwaysObtainSourceFile -SourceFolderPath $pkgSrvShr -SourceFolderPathType UncNetworkPath -verbose


#Code below to delete the standard programs created by Msi.

$delprogs=@("Per-system attended","Per-system unattended","Per-system uninstall","Per-user attended","Per-user unattended","Per-user uninstall")

  

foreach($pro in $delprogs)

{

  $dpgm=Get-CMPackage -Id $pkgID | Get-CMProgram -ProgramName $pro

  if($dpgm -ne $null)

  {

   Remove-CMProgram -PackageId $pkgID -ProgramName $pro -force -verbose

  }

}

}


#$pkgid=CAS00098 - cisco webex 7.3.3


$pkgid=$mypackage.PackageID;


#Find out how to enable Binary differential replication




$pgm1=Get-CMPackage -Id $pkgID | Get-CMProgram -ProgramName "InstallProgram"

$pgm2=Get-CMPackage -Id $pkgID | Get-CMProgram -ProgramName "SilentInstall"

$pg3=Get-CMPackage -Id $pkgID | Get-CMProgram -ProgramName "Uninstall"


if(($pgm1 -eq $null)-and ($installcmdline -ne ""))

{

  New-CMProgram -CommandLine $cmdline -PackageId $pkgID -StandardProgramName $stdpgmname -DiskSpaceRequirement $space -DiskSpaceUnit $dunit -Duration 720 -ProgramRunType WhetherOrNotUserIsLoggedOn -RunMode RunWithAdministrativeRights -RunType Normal -UserInteraction 1 -verbose

}

if(($pgm2 -eq $null) -and ($bincommandline -ne ""))

{

  New-CMProgram -CommandLine $bincommandline -PackageId $pkgID -StandardProgramName $binstall -DiskSpaceRequirement $space -DiskSpaceUnit $dunit -Duration 720 -ProgramRunType WhetherOrNotUserIsLoggedOn -RunMode RunWithAdministrativeRights -RunType Hidden -UserInteraction 0 -verbose

}

if(($pgm3 -eq $null) -and ($uincommandline -ne ""))

{

  New-CMProgram -CommandLine $uincommandline -PackageId $pkgID -StandardProgramName $unin -DiskSpaceRequirement "Unknown" -Duration 720 -ProgramRunType WhetherOrNotUserIsLoggedOn -RunMode RunWithAdministrativeRights -RunType Normal -UserInteraction 0 -verbose

}



read-host "Please enable Binary replication and press enter to start distribution"



#syntax

#Start-CMContentDistribution -DeploymentPackageId <String[]> [-CollectionName <String> ] [-DistributionPointGroupName <String> ] [-DistributionPointName <String> ] [-Confirm] [-WhatIf] [ <CommonParameters>]


#get all DP groups and distribute package to each group

Get-CMDistributionPointGroup | %{Start-CMContentDistribution -PackageId $pkgID -DistributionPointGroupName $_.Name -verbose}


#below two servers are not part of any DP grop si distribute separately.

Start-CMContentDistribution -PackageId $pkgID -DistributionPointName "dp1.mydomain.com" -verbose

Start-CMContentDistribution -PackageId $pkgID -DistributionPointName "dp2.mydomain.com" -verbose


#Enter N or enable read-host for enabling collection creation choice. yes or no

$a="Y" #read-host "Create collection Y or N"


if($a -eq "Y")

{


#Script below for collection creation


   write-host "Creating a collection with Name: $clctnName"  

  


    $cmnt="";


    $pkg=Get-CMPackage -Id $pkgID | select Name,Version

    if($pkg -ne $null)

    {

     $cmnt=$pkg.Name+" "+$pkg.Version

    }


    #$rfrshScd=$_.RefreshSchedule; #type <IResultObject>



    $clctn=Get-CMDeviceCollection -Name $clctnName


    if($clctn -eq $null)

    {

     write-host "Collection not found, creation collection"

     New-CMDeviceCollection -LimitingCollectionId $lmtClctn -Name $clctnName -Comment $cmnt -RefreshSchedule $rfrshScd  -RefreshType Periodic -verbose

     $clctn=Get-CMDeviceCollection -Name $clctnName

     Add-CMDeviceCollectionQueryMembershipRule -Collection $clctn -QueryExpression $qStmt -RuleName $clctn.Name -verbose

     #move to the self service folder

     Move-CMObject -FolderPath "CAS:\DeviceCollection\_Software Deployment Collections\" -InputObject $clctn -verbose

     write-host "Collection created and moved to self services folder"

    }

    else

    {

     write-host "Collection already exists, not created again"

    }

} #end of collection creation Y

else #If user selects N for collection creation.

{

  "No collection created"

}

}
























































































































































-----------------------------------------------
email: lanabhat@gmail.com
Phone: 9743289373
Please provide your suggestions and also feel free to ask your queries.
-----------------------------------------------