System Center Configuration Manager
8 TopicsDisable Exclusive Mode for All Audio Devices via PS
Hi all 🙂 Currently I am working on a script that will disable Exclusive Mode for all audio devices in Windows 10. So far I created this script: $Registry_Key = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Capture\*\*\" Get-ItemProperty -path $Registry_Key -name "{b3f8fa53-0004-438e-9003-51a46e139bfc},3" -ErrorAction SilentlyContinue | % { Set-ItemProperty -path $_.PSPath -name "{b3f8fa53-0004-438e-9003-51a46e139bfc},3" "0" } When I ran it as administrator I can see that it can find requested value on all registry keys under: "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Capture\*\*\" But scripts ends with permission denied error: PS C:\WINDOWS\system32> $Registry_Key = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Capture\*\*\" Get-ItemProperty -path $Registry_Key -name "{b3f8fa53-0004-438e-9003-51a46e139bfc},3" -ErrorAction SilentlyContinue | % { Set-ItemProperty -path $_.PSPath -name "{b3f8fa53-0004-438e-9003-51a46e139bfc},3" "0" } Set-ItemProperty : Requested registry access is not allowed. At line:2 char:123 + ... tinue | % { Set-ItemProperty -path $_.PSPath -name "{b3f8fa53-0004-43 ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : PermissionDenied: (HKEY_LOCAL_MACH...073}\Properties:String) [Set-ItemProperty], SecurityException + FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShell.Commands.SetItemPropertyCommand Set-ItemProperty : Requested registry access is not allowed. At line:2 char:123 + ... tinue | % { Set-ItemProperty -path $_.PSPath -name "{b3f8fa53-0004-43 ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : PermissionDenied: (HKEY_LOCAL_MACH...3b4}\Properties:String) [Set-ItemProperty], SecurityException + FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShell.Commands.SetItemPropertyCommand PS C:\WINDOWS\system32> So I know that at least the finding part is working properly. I created a script in MECM and deployed for test computer as the script should be ran with System Account permission and it ends with successful state but values are not being changed. Could someone share some advice regarding this case? Thanks Damian8.7KViews0likes3CommentsNeed powershell script to update microsoft edge in wvd environment
> Need help in creating a powershell script to update Microsoft Edge in WVD environment ( VM's ) > OS : Windows 2019 Server Requirement steps: 1 - close all sessions in the WVD VM. 2 - launch Edge and open the About page 3 - close edge after a couple of mins and then update it 4. a lot of time through the edge browser is just pending a restart to finish installing it. So is there a way to also force it to check for an update to be included in the script.10KViews0likes3CommentsBug in Get-CMSoftwareUpdateDeploymentStatus cmdlet
When I run the Get-CMSoftwareUpdateDeploymentStatus cmdlet I get the following message; Get-CMSoftwareUpdateDeploymentStatus : Operation could not complete because the currently connected account does not have the required security rights to perform this operation. I have the Full Administrator role I can run Get-CMPackageDeployment -DeploymentId "XX12008C" | Get-CMPackageDeploymentStatus and Get-CMApplicationDeployment -DeploymentId "{9462...43F34}" | Get-CMApplicationDeploymentStatus both work flawlessly but I can't do the same for Software Updates I run the following command; Get-CMSoftwareUpdateDeployment -DeploymentId "{7047...d3fe}" | Get-CMSoftwareUpdateDeploymentStatus644Views0likes0CommentsRun Script from SCCM
I am a novice at PowerShell. I have a request to run a script from SCCM to install a list of printer drivers. Script is as follows... # Ricoh Universal Print Driver Get-ChildItem "\\server\d$\Print_Drivers\Ricoh\Universal Print Driver ver4_27\disk1" -Recurse -Filter "*.inf" | ForEach-Object { PNPUtil.exe /add-driver $_.FullName /install } # Ricoh SP3410dn Print Driver Get-ChildItem "\\server\d$\Print_Drivers\Ricoh\SP 3410DN\PCL6\DISK1" -Recurse -Filter "*.inf" | ForEach-Object { PNPUtil.exe /add-driver $_.FullName /install } # Ricoh SP3510dn Print Driver Get-ChildItem "\\server\d$\Print_Drivers\Ricoh\SP 3510DN\PCL6\DISK1" -Recurse -Filter "*.inf" | ForEach-Object { PNPUtil.exe /add-driver $_.FullName /install } # Ricoh SPC232dn Print Driver Get-ChildItem "\\server\d$\Print_Drivers\Ricoh\SP C232DN\PCL6\DISK1" -Recurse -Filter "*.inf" | ForEach-Object { PNPUtil.exe /add-driver $_.FullName /install } # HP T1300 Print Driver Get-ChildItem "\\server\d$\Print_Drivers\HP\T1300 PS Server 2016\win_x64_ps3_drv\win_x64_ps3_drv" -Recurse -Filter "*.inf" | ForEach-Object { PNPUtil.exe /add-driver $_.FullName /install } # Zebra ZDesigner GX420t Print Driver Get-ChildItem "\\server\d$\Print_Drivers\Other\Zebra\ZD5-1-16-7110\ZBRN" -Recurse -Filter "*.inf" | ForEach-Object { PNPUtil.exe /add-driver $_.FullName /install } I can run this script locally on a machine & it runs fine, takes about 90 seconds to complete. When I create an application for it in SCCM & deploy it, its like it doesn't have time to complete the installs before PowerShell shuts down. Then the app shows as failed in Software Center. How do I make it wait to finish running the script before closing out PowerShell?3.9KViews0likes5CommentsPowerShell Automation for Verifying MST
Just finished putting together a script to Apply an MST to an MSI then read out the property table. This is for an automation process to verify a submited MSI and MST meet our packaging standards. Need a little sanity check as working with COM objects is not a strong point for me. Really want to make sure I am closing the files correctly after applying the transform then querying the database. I wasn't able to delete the temp files running in Powershell ISE until I did the ReleaseComObject. I didn't have to do that when working with the straight MSI and just pull the properties from it so I hope this is not corrupting any files. # Apply MST to an MSI # Based on Code from: https://hinchley.net/articles/update-cab-file-and-msi-transform-via-command-line/ $SourceMSI = "C:\Temp\MSI\MSI-x64.msi" $SourceMST = "C:\Temp\MSI\MSI.mst" $TempMSI = "$SourceMSI.tmp" $TempMST = "$SourceMST.tmp" Copy-Item $SourceMSI $TempMSI -Force Copy-Item $SourceMST $TempMST -Force $WindowsInstaller = New-Object -ComObject WindowsInstaller.Installer #Open the database in Direct read/write without Transaction (2) $MSIDatabase1 = $WindowsInstaller.GetType().InvokeMember('OpenDatabase' , 'InvokeMethod' , $Null, $WindowsInstaller, @($TempMSI, 2)) #$MSIDatabase1.applytransform($TempMST, 0) $MSIDatabase1.GetType().InvokeMember('ApplyTransform' , 'InvokeMethod' , $Null , $MSIDatabase1 , @($TempMST, 0)) $Query = ("SELECT Property,Value FROM Property") #Opens a data view to the MSI based on the query created. $View = $MSIDatabase1.GetType().InvokeMember('OpenView', 'InvokeMethod', $null, $MSIDatabase1, ($Query)) $null = $View.GetType().InvokeMember('Execute', 'InvokeMethod', $null, $View, $null) $hash = @{} # Add File information (Note this adds the full File information Porperties so can call with <Var>.File |Select * $hash.Add('File',$TempMSI) WHILE ($Record = $View.GetType().InvokeMember('Fetch', 'InvokeMethod', $null, $View, $null)) { $name = $Record.GetType().InvokeMember('StringData', 'GetProperty', $null, $Record, 1) $value = $hashMSIValue = $Record.GetType().InvokeMember('StringData', 'GetProperty', $null, $Record, 2) $hash.Add($name,$value) } # Push Hash table into a PSCustom object $msiProperties = [pscustomobject]$hash # I'm not sure If I have everything required to close out here properly from applying the transform. $null = $MSIDatabase1.GetType().InvokeMember('Commit' , 'InvokeMethod' , $Null , $MSIDatabase1 , $Null) $null = $view.GetType().InvokeMember('Close', 'InvokeMethod', $null, $view, $null) # Really important part to be able to release the opened files and delete $null = [Runtime.Interopservices.Marshal]::ReleaseComObject($view) $null = [Runtime.Interopservices.Marshal]::ReleaseComObject($MSIDatabase1) $null = [Runtime.Interopservices.Marshal]::ReleaseComObject($WindowsInstaller) [GC]::Collect()2.1KViews0likes0CommentsCalculate Percent on Compliance SCCM Powershell by Device collection
I have a function that pulls compliance status of a software update deployment (assignment ID). I want to configure this to calculate percent of the status types (Success, Error, In Progress, Unknown) and I would also like to pull compliance status based on device collection name instead of the deployment ID as it is shown below. What I want to accomplish is automatically take a list of device collection names and run a software update deployment which organizes each collection by compliance percent (for each status), and then receive it by email every morning. I have several locations based on device collection, and I want to be able to differentiate which locations and devices are the problematic ones. This method makes tracking and reporting much easier and SCCM console will not have to be launched each individual time to get reporting. function Get-SCCMSoftwareUpdateStatus { [CmdletBinding()] param( [Parameter()] [switch] $DeploymentIDFromGUI, [Parameter(Mandatory = $false)] [Alias('ID', 'AssignmentID')] [string] $DeploymentID, [Parameter(Mandatory = $false)] [ValidateSet('Success', 'InProgress', 'Error', 'Unknown')] [Alias('Filter')] [string] $Status ) BEGIN { $Site_Code = 'ABC' $Site_Server = 'SYSTEMCENTERSERVERNAME' $HasErrors = $False if ($Status -eq 'Success') { $StatusType = 1 } if ($Status -eq 'InProgress') { $StatusType = 2 } if ($Status -eq 'Unknown') { $StatusType = 4 } if ($Status -eq 'Error') { $StatusType = 5 } } PROCESS { try { if ($DeploymentID -and $DeploymentIDFromGUI) { Write-Error "Select the DeploymentIDFromGUI or DeploymentID Parameter. Not Both" $HasErrors = $True throw } if ($DeploymentIDFromGUI) { $ShellLocation = Get-Location Import-Module (Join-Path $(Split-Path $env:SMS_ADMIN_UI_PATH) ConfigurationManager.psd1) #Checking to see if module has been imported. If not abort. if (Get-Module ConfigurationManager) { Set-Location "$($Site_Code):\" $DeploymentID = Get-CMSoftwareUpdateDeployment | select AssignmentID, AssignmentName | Out-GridView -OutputMode Single -Title "Select a Deployment and Click OK" | Select -ExpandProperty AssignmentID Set-Location $ShellLocation } else { Write-Error "The SCCM Module wasn't imported successfully. Aborting." $HasErrors = $True throw } } if ($DeploymentID) { $DeploymentNameWithID = Get-WMIObject -ComputerName $Site_Server -Namespace root\sms\site_$Site_Code -class SMS_SUMDeploymentAssetDetails -Filter "AssignmentID = $DeploymentID" | select AssignmentID, AssignmentName $DeploymentName = $DeploymentNameWithID.AssignmentName | select -Unique } else { Write-Error "A Deployment ID was not specified. Aborting." $HasErrors = $True throw } if ($Status) { $Output = Get-WMIObject -ComputerName $Site_Server -Namespace root\sms\site_$Site_Code -class SMS_SUMDeploymentAssetDetails -Filter "AssignmentID = $DeploymentID and StatusType = $StatusType" | ` select DeviceName, CollectionName, @{Name = 'StatusTime'; Expression = {$_.ConvertToDateTime($_.StatusTime) }}, @{Name = 'Status' ; Expression = {if ($_.StatusType -eq 1) {'Success'} elseif ($_.StatusType -eq 2) {'InProgress'} elseif ($_.StatusType -eq 5) {'Error'} elseif ($_.StatusType -eq 4) {'Unknown'} }} } else { $Output = Get-WMIObject -ComputerName $Site_Server -Namespace root\sms\site_$Site_Code -class SMS_SUMDeploymentAssetDetails -Filter "AssignmentID = $DeploymentID" | ` select DeviceName, CollectionName, @{Name = 'StatusTime'; Expression = {$_.ConvertToDateTime($_.StatusTime) }}, @{Name = 'Status' ; Expression = {if ($_.StatusType -eq 1) {'Success'} elseif ($_.StatusType -eq 2) {'InProgress'} elseif ($_.StatusType -eq 5) {'Error'} elseif ($_.StatusType -eq 4) {'Unknown'} }} } if (-not $Output) { Write-Error "A Deployment with ID: $($DeploymentID) is not valid. Aborting" $HasErrors = $True throw } } catch { } finally { if (($HasErrors -eq $false) -and ($Output)) { Write-Output "" Write-Output "Deployment Name: $DeploymentName" Write-Output "Deployment ID: $DeploymentID" Write-Output "" Write-Output $Output | Sort-Object Status } } } END {} }4KViews0likes10CommentsPowershell for SCCM
I am new to Powershell and I want to run a powershell to query to SCCM Deployement status. 1)If appenforcement state is 1000 or 1001 for multple application names then the powershell output should be TRUE else FALSE. 2)IF the query inside for-each loop does not return any row ,then the counter must be incremented. If the output from 1 is FALSE or counter>0 in step 2 then final output should be FALSE else true PFB the query $ApplicationName = "Add Support Group,Notepad-PlusPlus-7.6.6" $AppNames = $ApplicationName -split "," $sqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter $dataTable = New-Object System.Data.DataTable $dataSource = "dataSource" $database = "database" # Get Start Time $startDTM = (Get-Date) # Open a connection #cls #Write-host "Opening a connection to '$database' on '$dataSource'" #Using windows authentication, or.. $connectionString = "Server=$dataSource;Database=$database;Integrated Security=SSPI;" # Using SQL authentication #$connectionString = "Server=$dataSource;Database=$database;uid=ConfigMgrDB_Read;pwd=Pa$$w0rd;Integrated Security=false" $connection = New-Object System.Data.SqlClient.SqlConnection $connection.ConnectionString = $connectionString $connection.Open() $command = $connection.CreateCommand() foreach ($AppName in $AppNames) { Write-Output $AppName $query = " select distinct ae.AppEnforcementState from v_R_System_Valid s1 join vAppDTDeploymentResultsPerClient ae on ae.ResourceID=s1.ResourceID join v_CICurrentComplianceStatus ci2 on ci2.CI_ID=ae.CI_ID AND ci2.ResourceID=s1.ResourceID join v_ApplicationAssignment aa on ae.AssignmentID = aa.AssignmentID where ae.AppEnforcementState is not null and aa.ApplicationName = '$AppName' and s1.netbios_name0 =$Computer " $command.CommandText = $query $sqlAdapter.SelectCommand = $command $result = $command.ExecuteReader() $result.Close() $result = $sqlAdapter.Fill($dataTable) } Write-Output -Verbose $dataTable $connection.Close() write-host "Starting after connection close" $success for($i=0;$i -lt $dataTable.Rows.Count;$i++) { Write-Output $dataTable.Rows[$i][0] if ( $dataTable.Rows[$i][0] -eq 1000 -Or $dataTable.Rows[$i][0] -eq 1001 ){ $success = "true" } else { $success = "false" break } } Write-Output $success1.2KViews0likes1CommentWindows 10 Subscription Activation via Powershell
We recently purchased E3 Subscription licenses for Windows 10. Microsoft's documentation states for exisiting enterprise deployments, the following script should be ran via a command line: @echo off FOR /F "skip=1" %%A IN ('wmic path SoftwareLicensingService get OA3xOriginalProductKey') DO ( SET "ProductKey=%%A" goto InstallKey ) :InstallKey IF [%ProductKey%]==[] ( echo No key present ) ELSE ( echo Installing %ProductKey% changepk.exe /ProductKey %ProductKey% ) I'm attempting to re-write this in powershell so we can use it as a remediation step in a configuration baseline in SCCM. Below is the powershell script I wrote: $ProductKey = (Get-CimInstance -ClassName SoftwareLicensingService).OA3xOriginalProductKey if ($ProductKey){ start-process c:\Windows\System32\changePK.exe -ArgumentList "/ProductKey $ProductKey" } The script runs without error, but it's not actually completing the intended task (activating the embedded windows 10 pro key). I'm not sure where I'm going wrong. I'm pretty new to powershell so any assistance would be greatly appreciated.42KViews1like8Comments