Thursday, 24 October 2024

SCCM Configuration Baseline to Initiate Available Task Sequence

 PowerShell Script Monitor

Function Get-RegistryValue12 {

        param (

            [parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]$Path,

            [parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]$Name

        )

        Return (Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue).$Name

    }

$compliance = "Compliant"

$Registry = "HKLM:\SOFTWARE\SOFTWARE\WOW6432Node\Notepad++"

$name = "InstallerLanguage"

$value = Get-RegistryValue12 -path $registry -name $name

$Ver = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").currentBuild

If ($Ver -like '1033')

{

$compliance = 'Non-Compliant'

}

$compliance


PowerShell Script Remediation

Function Execute-TaskSequence {

    Param (

        [parameter(Mandatory = $true)]

        [string]$Name

    )

    Try {

        Write-Host "Connecting to the SCCM client Software Center..."

        $softwareCenter = New-Object -ComObject "UIResource.UIResourceMgr"

    }

    Catch {

        Throw "Could not connect to the client Software Center."

    }

    If ($softwareCenter) {

        Write-Host "Searching for deployments for task sequence [$name]..."

        $taskSequence = $softwareCenter.GetAvailableApplications() | Where-Object { $_.PackageName -eq "$Name" }

        If ($taskSequence) {

            $taskSequenceProgramID = $taskSequence.ID

            $taskSequencePackageID = $taskSequence.PackageID

            Write-Host "Found task sequence [$name] with package ID [$taskSequencePackageID]."

            # Execute the task sequence

            Try {

                Write-Host "Executing task sequence [$name]..."

                $softwareCenter.ExecuteProgram($taskSequenceProgramID,$taskSequencePackageID,$true)

                Write-Host "Task Sequence executed."

            }

            Catch {

                Throw "Failed to execute the task sequence [$name]"

            }

        }

        Else {

            Write-Host "No Deployments found matching name = [$name]!"

            exit 100

        }

    }

}

Execute-TaskSequence -name "Custom Task Sequence"

Tuesday, 22 October 2024

SCCM Collection Optimization using PowerShell Script

 SQL Query to Get the current collection evaluation schedule


Select

CG.CollectionName,

CG.SITEID AS [Collection ID],

CASE VC.CollectionType

WHEN 0 THEN ‘Other’

WHEN 1 THEN ‘User’

WHEN 2 THEN ‘Device’

ELSE ‘Unknown’ END AS CollectionType,

CG.schedule, case

WHEN CG.Schedule like ‘%000102000’ THEN ‘Every 1 minute’

WHEN CG.Schedule like ‘%00010A000’ THEN ‘Every 5 mins’

WHEN CG.Schedule like ‘%000114000’ THEN ‘Every 10 mins’

WHEN CG.Schedule like ‘%00011E000’ THEN ‘Every 15 mins’

WHEN CG.Schedule like ‘%000128000’ THEN ‘Every 20 mins’

WHEN CG.Schedule like ‘%000132000’ THEN ‘Every 25 mins’

WHEN CG.Schedule like ‘%00013C000’ THEN ‘Every 30 mins’

WHEN CG.Schedule like ‘%000150000’ THEN ‘Every 40 mins’

WHEN CG.Schedule like ‘%00015A000’ THEN ‘Every 45 mins’

WHEN CG.Schedule like ‘%000100100’ THEN ‘Every 1 hour’

WHEN CG.Schedule like ‘%000100200’ THEN ‘Every 2 hours’

WHEN CG.Schedule like ‘%000100300’ THEN ‘Every 3 hours’

WHEN CG.Schedule like ‘%000100400’ THEN ‘Every 4 hours’

WHEN CG.Schedule like ‘%000100500’ THEN ‘Every 5 hours’

WHEN CG.Schedule like ‘%000100600’ THEN ‘Every 6 hours’

WHEN CG.Schedule like ‘%000100700’ THEN ‘Every 7 hours’

WHEN CG.Schedule like ‘%000100B00’ THEN ‘Every 11 Hours’

WHEN CG.Schedule like ‘%000100C00’ THEN ‘Every 12 Hours’

WHEN CG.Schedule like ‘%000101000’ THEN ‘Every 16 Hours’

WHEN CG.Schedule like ‘%000100008’ THEN ‘Every 1 days’

WHEN CG.Schedule like ‘%000100010’ THEN ‘Every 2 days’

WHEN CG.Schedule like ‘%000100028’ THEN ‘Every 5 days’

WHEN CG.Schedule like ‘%000100038’ THEN ‘Every 7 Days’

WHEN CG.Schedule like ‘%000192000’ THEN ‘1 week’

WHEN CG.Schedule like ‘%000080000’ THEN ‘Update Once’

WHEN CG.SChedule = ” THEN ‘Manual’

END AS [Update Schedule],

Case VC.RefreshType

when 1 then ‘Manual’

when 2 then ‘Scheduled’

when 4 then ‘Incremental’

when 6 then ‘Scheduled and Incremental’

else ‘Unknown’

end as RefreshType,

VC.MemberCount

from

dbo.collections_g CG

left join v_collections VC on VC.SiteID = CG.SiteID

order by

CG.Schedule DESC


Powershell Script to update the evaluation schedule


# site code.

$sitecode = '123'


# name of server hosting the sms provider.

$provider = 'ServerName'


# create a recuring interval token with a cycle of x days.

# the start time will be randomised, but always on the hour.

function new-token($days = 1) {

  $class = gwmi -list -name root\sms\site_$sitecode -class sms_st_recurinterval -comp $provider

  $interval = $class.createinstance()

  $interval.dayspan = $days

  $interval.starttime = get-date (get-date '1/1/2016').addhours((get-random -max 24)) -format yyyyMMddHHmmss.000000+***

  return $interval

}


# get the names of all collections enabled for incremental updates.

function get-incremental() {

  $collections = @()

  gwmi -name root\sms\site_$sitecode -class sms_collection -comp $provider | %{

    $collection = [wmi]$_.__path

    if ($collection.refreshtype -band 4 -and $collection.collectionid -notlike 'sms*') {

      $collections += $collection.name

    }

  }

  return $collections

}


# configure the refresh cycle for an array of collections.

# set $type to 2 for periodic refresh only, and 6 for incremental and periodic.

# set $days to the number days between each periodic refresh.

function set-schedule([array]$collections, $type, $days) {

  $collections | %{

    if (! ($collection = gwmi -name root\sms\site_$sitecode -class sms_collection -comp $provider -filter "name = '$_'")) { return }

    $collection.refreshtype = $type

    $collection.refreshschedule = new-token $days

    #$collection.psbase()

    $collection.put() | out-null

  }

}


# disable incremental updates.

# i.e. enable periodic updates only, with a refresh cycle of 1 day.

function disable-incremental([array]$collections) {

  set-schedule $collections 2 7

}


# enable incremental updates.

# i.e. enable incremental and periodic updates, with a refresh cycle of 7 days.

function enable-incremental([array]$collections) {

  set-schedule $collections 6 7

}

#To retrieve the name of all collections enabled for incremental updates:


#get-incremental

#To disable incremental updates on all collections listed in a file named disable.txt, and enable periodic updates with a daily cycle:


disable-incremental (get-content "C:\Temp\Collection.txt")

#To enable incremental and periodic updates on all collections listed in a file named disable.txt, with a weekly periodic refresh cycle:


#enable-incremental (get-content enable.txt)

Thursday, 3 October 2024

Intune Blocking Store App and allow them updated

 Below configuration profile will help to block the store app 

Administrative Templates\Windows Components\Store

Turn off the Store application (User) and set Enabled


Administrative Templates\Start Menu and Taskbar

Do not allow pinning Store app to the Taskbar (User) and set Enabled


Regardless of how you are blocking or allowing the Microsoft Store, remembering that the store needs to be available to allow for apps from Microsoft Intune to be deployed, we should at least configure devices to allow for updates


Administrative Templates\Windows Components\Store

Allow apps from Microsoft app store to auto update


You can also use the remediation script to allow store app auto update


Detection Script


$Path = "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore"

$Name = "AutoDownloaded"

$Value = 4


Try {

    $Registry = Get-ItemProperty -Path $Path -Name $Name -ErrorAction Stop | Select-Object -ExpandProperty $Name

    If ($Registry -eq $Value){

        Write-Output "Compliant"

        Exit 0

    } 

    Write-Warning "Not Compliant"

    Exit 1

Catch {

    Write-Warning "Not Compliant"

    Exit 1

}


Remediation Script


Write-Host "Required Auto Update"

$store = "HKLM:\SOFTWARE\Policies\Microsoft\WindowsStore"

If (!(Test-Path $store)) {

    New-Item $store

}

Set-ItemProperty $store AutoDownloaded -Value 4


Tuesday, 24 September 2024

SCCM Configuration Item to Start, Stop, Refresh and Restart Services on client devices

In this post, we will be discussing the topic of how to Enable or Disable Services and how to Start, Stop, Refresh and Restart Services on client device

---Monitor Script

# Define the service name

$serviceName = "PFERemediation"

# Confirm the service status

$service = Get-Service -Name $serviceName

 # Check if the service is stopped and disabled

if ($service.Status -eq 'Stopped' -and $service.StartType -eq 'Disabled') {

    Write-Output "compliance"

} else {

    Write-Output "non-compliance"

}

--Remediation Script

# Define the service name

$serviceName = "PFERemediation"

 # Stop the service

Stop-Service -Name $serviceName -Force

# Disable the service

Set-Service -Name $serviceName -StartupType Disabled

 # Confirm the service status

$service = Get-Service -Name $serviceName

# Check if the service is stopped and disabled

if ($service.Status -eq 'Stopped' -and $service.StartType -eq 'Disabled') {

    Write-Output "compliance"

} else {

    Write-Output "non-compliance"

}

More command line 

Automatic (Delayed Start))​

Set-Service -Name "ServiceName" -StartupType AutomaticDelayedStart​

OR​

(Automatic)​

Set-Service -Name "ServiceName" -StartupType Automatic​

OR​

(Manual)​

Set-Service -Name "ServiceName" -StartupType Manual​

(Automatic (Delayed Start))​

Set-Service -Name "ServiceName" -StartupType AutomaticDelayedStart -Status Running​

OR​

(Automatic)​

Set-Service -Name "ServiceName" -StartupType Automatic -Status Running​

OR​

(Manual)​

Set-Service -Name "ServiceName" -StartupType Manual -Status Running

Set-Service -Name "ServiceName" -StartupType Disabled -Status Stopped

Thursday, 19 September 2024

SCCM WMI Repair using powershell script

 Script 1:

cls

Cd C:\temp\PSTools

$computers = Get-Content "C:\Temp\repairWMI\Input.txt"


Foreach ($computer in $computers)

{

 $filecopy = "\\"+$computer+"\C$"

 $comp = "\\"+$computer

 if (Test-Path $filecopy)

  {

  Copy-Item "C:\Temp\repairWMI\TorepairWMI.ps1" -Destination $filecopy -Force

  Start-sleep 5 

  .\PsExec.exe -i -s $comp PowerShell.exe -noninteractive -File "C:\TorepairWMI.ps1"

   

  }


}

 Script 2:

Function Repair-WMI {

        

        CD C:\Windows\System32\WBEM

        cmd /C "dir /b *.mof *.mfl | findstr /v /i uninstall > moflist.txt & for /F %s in (moflist.txt) do mofcomp %s"

       

        CD "C:\Program Files\Microsoft Policy Platform"

        cmd /C "mofcomp ExtendedStatus.mof"

        # Check PATH

                # Stop WMI

        Stop-Service -Force ccmexec -ErrorAction SilentlyContinue

        Stop-Service -Force winmgmt


        # WMI Binaries

        [String[]]$aWMIBinaries=@("unsecapp.exe","wmiadap.exe","wmiapsrv.exe","wmiprvse.exe","scrcons.exe")

        foreach ($sWMIPath in @(($ENV:SystemRoot+"\System32\wbem"),($ENV:SystemRoot+"\SysWOW64\wbem"))) {

            if(Test-Path -Path $sWMIPath){

                push-Location $sWMIPath

                foreach($sBin in $aWMIBinaries){

                    if(Test-Path -Path $sBin){

                        $oCurrentBin=Get-Item -Path  $sBin

                        & $oCurrentBin.FullName /RegServer

                    }

                    else{

                        # Warning only for System32

                        if($sWMIPath -eq $ENV:SystemRoot+"\System32\wbem"){

                            Write-Warning "File $sBin not found!"

                        }

                    }

                }

               

            }

        }

}

Repair-WMI

Start-sleep 10

Remove-Item C:\TorepairWMI.PS1 -Force

Tuesday, 30 July 2024

PowerShell Script - SCCM Remove In progress packages from all Distribution Points

 function ExecuteSqlQuery ($Server, $Database, $SQLQuery) { 

     $Datatable = New-Object System.Data.DataTable 

      

     $Connection = New-Object System.Data.SQLClient.SQLConnection 

     $Connection.ConnectionString = "server='$Server';database='$Database';trusted_connection=true;" 

     $Connection.Open() 

     $Command = New-Object System.Data.SQLClient.SQLCommand 

     $Command.Connection = $Connection 

     $Command.CommandText = $SQLQuery 

     $Reader = $Command.ExecuteReader() 

     $Datatable.Load($Reader) 

     $Connection.Close() 

      

     return $Datatable 

 }


Cls



$packagetoremove  = Get-Content -LiteralPath "D:\Script-New\ToremovePackagesFromInProgressDPs\Input.txt"


$count = $report.count


$series = 1



Foreach ($p in $packagetoremove)

{


 [string] $Server= "Servername" 

 [string] $Database = "CM_123" 

 [string] $UserSqlQuery= $("SELECT vSMS_DPStatusDetails.PackageID,v_Package.Name ,vSMS_DPStatusDetails.DPName,CASE

WHEN vSMS_DPStatusDetails.MessageState = 1 THEN 'Success'WHEN vSMS_DPStatusDetails.MessageState = 2 THEN 'InProgress'WHEN vSMS_DPStatusDetails.MessageState = 4 THEN 'Failed'END AS [State]

FROM            vSMS_DPStatusDetails INNER JOIN

                         v_Package ON vSMS_DPStatusDetails.PackageID = v_Package.PackageID

WHERE vSMS_DPStatusDetails.PackageID = 'CM0004DF' and vSMS_DPStatusDetails.MessageState != '1'

GROUP BY vSMS_DPStatusDetails.DPName, vSMS_DPStatusDetails.MessageState,vSMS_DPStatusDetails.PackageID,v_Package.Name

ORDER BY State") 


  # declaration not necessary, but good practice  

  $Report = New-Object System.Data.DataTable 

 $Report = ExecuteSqlQuery $Server $Database $UserSqlQuery


 Foreach ($app in $report)

 {

  $pkgid = $app.PackageID

  $dp = $app.DPName

  $appname = $app.Name

   Write-Host "Removing "  $appname" from "  $dp ------- $series " From total of " $count


 

  Remove-CMContentDistribution -ApplicationName '$appname'  -DistributionPointName $dp -Force


  $app = " "

  

  $series++ 

   

 }


 $p = " "


 $report = " " 

 }


Wednesday, 13 March 2024

SCCM SQL Query to get Bit-locker Recovery Key

 

SELECT

cm.Name,

ck.RecoveryKeyId,

cv.VolumeGuid,

cvt.TypeName AS 'Volume Type',

RecoveryAndHardwareCore.DecryptString(ck.RecoveryKey, DEFAULT) AS RecoveryKey,

RecoveryAndHardwareCore.DecryptBinary(ck.RecoveryKeyPackage, DEFAULT) AS BitLockerRecoveryKeyPackage,

ck.LastUpdateTime

FROM RecoveryAndHardwareCore_Keys ck

INNER JOIN RecoveryAndHardwareCore_Volumes cv on ck.VolumeID = cv.ID

LEFT JOIN RecoveryAndHardwareCore_VolumeTypes cvt on cv.VolumeTypeId = cvt.Id

LEFT JOIN RecoveryAndHardwareCore_Machines_Volumes cmv on cv.Id = cmv.VolumeId

LEFT JOIN RecoveryAndHardwareCore_Machines cm on cmv.MachineId = cm.Id

SCCM Configuration Baseline to Initiate Available Task Sequence

 PowerShell Script Monitor Function Get-RegistryValue12 {         param (             [parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]...