Download and Install VSCode from
https://code.visualstudio.com/downloadAdventures in Powershell. These posts have been created as a record of the successful powershell commands I have used.
Download and Install VSCode from
https://code.visualstudio.com/download
Open the SCCM console and open Powershell ISE from the top left. Powershell ISE will open with a script containing the SCCM connection values.
Run the script to make a powershell drive connection to SCCM.
Test the connection using an SCCM cmdlet
Once you start working with Powershell soon or later you will have to get a grip of module version management. Basic Microsoft.Powershell.Core module cmdlets to manage modules are
Get-Module - List the modules imported in the current session or use -ListAvailable to show ones that can be imported from the PSModulePath.
Import-Module - Adds modules to the current session.
Remove-Module - Removes modules from the current session.
The full list of Microsoft.Powershell.Core modules are listed here
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/?view=powershell-7.4
You can get a feel for what these module commands do by following this exercise. The below screen shot was taken on on a vanilla Windows Server 2019.
Start a fresh Powershell ISE window
Get-Module to display the current modules loaded in the session.
Get-Adapter to display the network adapter info.
Get-Module to display the current modules loaded in the session. Notice that now NetAdapter and NetAdapter.Format.Helper appear in the list.
Remove-Module -Name NetAdapter
Get-Module this now displays the list of loaded modules but NetAdapter has been removed.
Let see what PowerShellGet version we have with our freshly installed Windows Server 2019:
Windows PowerShell 5.1 comes with PowerShellGet version 1.0.0.1, which doesn't include the NuGet provider. This provider is required by PowerShellGet when working with the PowerShell Gallery. As it is, PowerShellGet version 1.0.0.1 can't really do much. It can't even update itself with help from something else. That something else is the NuGet provider.
This subject is also covered in
Install-PackageProvider -Name NuGet -Force
Now that's installed upgrade the PowerShellGet
Install-Module PowerShellGet -AllowClobber -Force
Close and reopen the powershell interface.
It is recommended to set the Powershell Gallery as a trusted repository using
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
To List available module versions in the PSGallery
Find-Module -name <ModuleName>
param (
[Parameter (ValueFromPipeline=$true, Mandatory=$true)]
[string]$username = $null
)
$dn = (Get-ADUser $username).DistinguishedName
#Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn) | where {$_.name -like "*oracle*" -or $_.name -like "*FDM*"} | select -expand Name | sort name
Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn) -Properties description | select Name,description | sort name
#Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn) | where {$_.name -like "PERM-D-*"} | select -expand Name | sort name
#Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn) | select -expand Name | sort name
In this script, an operating system tool called klist is being called to update the machine account group memberships. It then triggers a GPO update. This would be useful where GPO security filtering has been limited to a group and new members have been added to the group for the GPO to apply to.
Consider adjusting the gpupdate call to restrict it machine or user as necessary.
param (
[Parameter (ValueFromPipeline=$true, Mandatory=$true)]
[string]$Groupname = $null
)
$TargetMachineList=get-adgroupmember $groupname | select -expand name | sort name
foreach ($compname in $TargetMachineList)
{
$online = test-connection -computername $compname -Beffersize 16 -count 1 -quiet
if ($online -like "true")
{
invoke-command -cn $compname -command {c:\windows\system32\klist -lh 0 -li 0x3e7 purge}
invoke-command -cn $compname -command {c:\windows\system32\gpupdate /force}
}
}
This code locates a XML code section and modifies it. It is based on a couple of articles:
https://gist.github.com/aadennis/1efa5015fca7b0ec23ee341d0665a067
https://superuser.com/questions/560329/how-to-modify-create-values-in-xml-files-using-powershell
The powershell is here followed by the structure of the target XML
#Checks the user config file
#Checks
the AllowBatchPrinting setting is set to false and changes it to false if not.
#Target Config File Name
$ConfigFileName = $env:LOCALAPPDATA+"\Microsoft\AppV\Client\VFS\5BC6440A-16C1-4529-B9B9-1A55D86892F5\ProgramFilesX86\Mitratech
Holdings Inc\DataStoreDSX\Searching
Client\HitecLabs.DataStore.SearchingClient.exe.config"
#Create XML object from file
$xml = [xml] (get-content -Raw $ConfigFileName)
#Check the
item number of the target item
$names=$xml.configuration.applicationSettings.'HitecLabs.DataStore.Client.Applications.VisualDataStoreHelperLibrary.Properties.Settings'.Setting.name
$count=0
foreach ($name in $names)
{
if ($name -like "AllowBatchPrinting")
{$item=$count}
else
{$count=$count+1}
}
#Read
current value of target value
$TargetSettingValue=$xml.configuration.applicationSettings.'HitecLabs.DataStore.Client.Applications.VisualDataStoreHelperLibrary.Properties.Settings'.Setting.item($item).value
#Change
value if necessary.
if ($TargetSettingValue="True"){$xml.configuration.applicationSettings.'HitecLabs.DataStore.Client.Applications.VisualDataStoreHelperLibrary.Properties.Settings'.Setting.item($item).value = "False"
$xml.Save($ConfigFileName)
}
Target XML structure partial file section:
<?xml version="1.0" encoding="utf-8"?>
<!--
Configuration settings for DataStore Searching Client
Application
-->
<configuration>
<configSections>
These sections removed
</sectionGroup>
</configSections>
<applicationSettings>
<HitecLabs.DataStore.Help.Properties.Settings>
<setting
name="DSSearchingClientHelpURL" serializeAs="String">
<value>http://servername/DSXHelp/SearchingClient/SearchingClient.htm</value>
</setting>
</HitecLabs.DataStore.Help.Properties.Settings>
<!-- Document Comparer setting for
document revisions dialog -->
<HitecLabs.DataStore.Client.Applications.VisualDataStoreHelperLibrary.Properties.Settings>
<setting
name="DocumentComparisonMethod" serializeAs="String">
<!--
0=Microsoft Word
1=Aspose.Words
-->
<value>0</value>
</setting>
<setting
name="MaxLogFileSizeToZipForEmailInMBs"
serializeAs="String">
<value>200</value>
</setting>
<setting
name="AllowBatchPrinting" serializeAs="String">
<value>False</value>
</setting>
<setting
name="PrintBatchSize" serializeAs="String">
<value>100</value>
</setting>
</HitecLabs.DataStore.Client.Applications.VisualDataStoreHelperLibrary.Properties.Settings>
Google around and you'll find various ways of automatically logging off idle users. None of them suited my requirements so I created a task scheduler coupled to a powershell script to manage it. The advantages of this approach are
Amazon Workspace Client can use Universal Resource Identifiers (URIs) to launch with predefined parameters such as the username and region code.
This code creates a URI file and makes a call to it. In practice addtional code would be used to determine the SAMAccountName and RegionCode
$SAMAccountName=mysamaccountname
$RegionCode=myRegionCode
$targetpath = 'workspaces://'+$SAMAccountName+'@'+$RegionCode+'?MFACode=push'
$line1 = '[InternetShortcut]' | Out-File $URIFile
$line2 = 'URL='+$targetpath | Out-File $URIFile -Append
$line3 = 'IconIndex = 0' | Out-File $URIFile -Append
$line4 = 'IconFile=C:\Program Files (x86)\Amazon Web Services, Inc\Amazon\WorkSpaces\workspaces.exe' | Out-File $URIFile -Append
Invoke-Item $URIFile
During a task sequence run, it is useful to set task sequence variables to set conditions for tasks.
If using the Microsoft Deployment Tookit (MDT) task sequence variables are set for example when a virtual machine or laptop is detected.
$SMSTSEnv.Value("IsVM") will return True for virtual machines
$SMSTSEnv.Value("IsLaptop") will return True for laptops
These items can then be queried to control if laptop orientated tasks should activate.
To set a custom task sequence variable in a powershell script first create the object then set the variable value.
$SMSTSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment -ErrorAction SilentlyContinue
$SMSTSEnv.Value("TestVar")="TestVarValue"
Task sequence task options can then be conditioned on the task sequence variable value
During a first logon to Windows 10 some time is taken to setup UWP apps for the user. During the build phase you may wish to remove some of the ones you do not need.
Microsoft.549981C3F5F10
Microsoft.BingWeather
Microsoft.DesktopAppInstaller
Microsoft.GetHelp
Microsoft.Getstarted
Microsoft.HEIFImageExtension
Microsoft.Microsoft3DViewer
Microsoft.MicrosoftEdge.Stable
Microsoft.MicrosoftOfficeHub
Microsoft.MicrosoftSolitaireCollection
Microsoft.MicrosoftStickyNotes
Microsoft.MixedReality.Portal
Microsoft.MSPaint
Microsoft.Office.OneNote
Microsoft.People
Microsoft.ScreenSketch
Microsoft.SkypeApp
Microsoft.StorePurchaseApp
Microsoft.VCLibs.140.00
Microsoft.VP9VideoExtensions
Microsoft.Wallet
Microsoft.WebMediaExtensions
Microsoft.WebpImageExtension
Microsoft.Windows.Photos
Microsoft.WindowsAlarms
Microsoft.WindowsCalculator
Microsoft.WindowsCamera
microsoft.windowscommunicationsapps
Microsoft.WindowsFeedbackHub
Microsoft.WindowsMaps
Microsoft.WindowsSoundRecorder
Microsoft.WindowsStore
Microsoft.Xbox.TCUI
Microsoft.XboxApp
Microsoft.XboxGameOverlay
Microsoft.XboxGamingOverlay
Microsoft.XboxIdentityProvider
Microsoft.XboxSpeechToTextOverlay
Microsoft.YourPhone
Microsoft.ZuneMusic
Microsoft.ZuneVideo
Run this script logged in as admin and elevated.
#get provisioned apps
$AppxProv = Get-AppxProvisionedPackage -Online
#Enter the Apps you want to keep into this array
$AppsToKeep = @("Microsoft.MicrosoftOfficeHub","Microsoft.WindowsCalculator","Microsoft.Office.OneNote","Microsoft.WindowsCamera")
#loop through them
foreach ($AppxProvItem in $AppxProv)
{
$AppxprvDN = $AppxProvItem | Select -expand DisplayName
if ($AppxprvDN -notin $AppsToKeep)
{
#Get the package full name
$AppxTargetPFN = Get-AppxPackage -Name $AppxPrvDN | Select -expand PackageFullName
#first remove the package from the logged on session
Remove-AppxPackage -Package $AppxTargetPFN
#then target the provisioned Appx version
$AppxPrvTarget = Get-AppxProvisionedPackage -Online | where{$_.DisplayName -like $AppxPrvDN}
$AppxPrvTargetPN = $AppxPrvTarget | Select -expand PackageName
Remove-AppxProvisionedPackage -Online -PackageName $AppxPrvTargetPN
}
}
Insert this at the top of a script to stop error information appearing in the output that you are trying to read!
$ErrorActionPreference= 'silentlycontinue'
C:\Windows\Web\Wallpaper\Windows\img0.jpg is typically the default wallpaper for Windows 10. As part of the OS can be tricky to change unless you adjust the permissions. This script was designed to run in an SCCM task sequence
$ScriptsPath = Split-Path - Parent $MyInvocation.MyCommand.Path
$img0new = $ScriptsPath+"\img0.jpg
$img0 = "C:\Windows\Web\Wallpaper\Windows\img0.jpg
#modify default permissions on img0.jpg
takeown /f $img0
icacls $img0 /Grant 'System:(F)'
Copy-Item -Path $img0new -Destination $img0 -Force
Article on how to produce pop-ups in powershell.
https://powershell.org/2013.04/powershell-popup
$wshell = New-Object -ComObject Wscript.Shell -ErrorAction Stop
$wshell.Popup("Are you looking at me?",0,"Hey!",48+4)