Tag Archives | PowerShell

Powershell script to find and run advertisements that are set to run when NoUserLoggedOn

I have been thinking about how to launch a SCCM package/program before logon. If the user logs on before SCCM executes (like right after a reboot), the NoUserLoggedOn requirement will not be met. GPO software deployment handles this by not allowing the user to log in until the software is installed.

What happens if you combine both software deployment via GPO and SCCM?

So my theory is that I could execute a script wrapped in a MSI and deployed via GPO software deployment. This script would then search for advertisements that are set to run “when no one is logged in” and execute them. Below is that script, not sure if the rest of my theory will work, but this is the first piece.

$AdvNoLogOn = (gwmi -Namespace ROOT\CCM\Policy\Machine\ActualConfig -Class CCM_SoftwareDistribution | where {$_.ADV_MandatoryAssignments -eq $true} | where {$_.PRG_PRF_UserLogonRequirement -eq "NoUserLoggedOn"})
$SMSCli = [wmiclass] "\root\ccm:SMS_Client"
foreach ($Adv in $AdvNoLogOn)
{
$PKGID= $Adv.PKG_PackageID
write-host $PKGID
$SCHEDMESS=(gwmi -Namespace ROOT\CCM\Policy\Machine\ActualConfig -Class CCM_Scheduler_ScheduledMessage | where {$_.ActiveMessage -like "*$PKGID*"})
write-host $SCHEDMESS.ScheduledMessageID
$SMSCLI.TriggerSchedule($SCHEDMESS.ScheduledMessageID)
}

Powershell signing, makecert.exe and group policy – Part 2

In the previous post I showed how to create self signed signing certs via the makecert tool. Once I made the pfx files, and signed my script, I need to make the server I was working see the certificate chain. I created a GPO and applied it to the server OU. I added the Root cert to Trusted Root Certification Authorities, and I added the Cert to Trusted Publishers Certificates. Now when I open a signed script on a server, I no longer have to change the Set-ExecutionPolicy RemoteSigned and add the network path to the Local Intranet zone.

Powershell signing, makecert.exe and group policy – Part 1

We don’t have a pki infrastructure at my current job, and I like to keep my powershell scripts on my network drive. So I needed a way to run my .ps1 files off a network drive. Setting Set-ExecutionPolciy to Unrestricted seemed like a bad idea. So I looked into using a signed script and setting Set-ExecutionPolicy to RemoteSigned. I could not justify $300 to buy a trused third party cert, so I looked at makecert.exe from the Windows SDK.

First step make the Root CA cert, private key, and pxf.

  1. makecert -n “CN=RootName” -a sha1 -eku 1.3.6.1.5.5.7.3.3 -r -sv Root.pvk Root.cer
  2. pvk2pfx.exe -pvk Root.pvk -spc Root.cer -pfx Root.pfx -pi password

makecert and pvk2pfx can be found in the Windows SDK or in the Visual Studio bin directory. First command results in a private key (.pvk) and a certificate (.cer). Second command makes a pfx out of the first 2.

Second step is to create a certificate from the root cert above.

  1. makecert -pe -n “CN=Certificate” -a sha1 -eku 1.3.6.1.5.5.7.3.3 -ic Root.cer -iv Root.pvk -sv Certificate.pvk Certificate.cer
  2. pvk2pfx.exe -pvk Certificate.pvk -spc Certificate.cer -pfx Certificate.pfx -pi password

Now we are ready to sign our powershell script.

  1. $cert = Get-PfxCertificate Certificate.pfx
  2. Set-AuthenticodeSignature -Filepath script.ps1 -Cert $cert

Probably can be combined into one line, but I am not a guru yet.

Next post will talk about how I added this certs above to all the servers.

PowerShell is great

Okay, I drank the Kool-Aid. PowerShell is awesome. The first thing I wanted to do was make sure my $profile is always the most current no matter what machine was on. In the past I had a batch file that I would run that would open my command prompt the way I wanted. I modified that so if PowerShell is installed, then get my profile up-to-date and then launch PowerShell. This is part of my current batch file:

IF NOT EXIST "c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" GOTO NO_PS
powershell -NoProfile $a=(Split-Path $profile -parent);if (!(Test-Path $a)) {New-Item $a -type directory};
powershell -NoProfile if (!(Test-Path $profile)) {Copy-Item %~dp0Scripts\Microsoft.PowerShell_profile.ps1 (Split-Path $profile -parent)}
powershell -NoProfile if (!(Compare-Object $(Get-Content $profile) $(Get-Content Scripts\Microsoft.PowerShell_profile.ps1)).Count -eq 0 ) {Copy-Item Scripts\Microsoft.PowerShell_profile.ps1 (Split-Path $profile -parent)}
@start  %COMSPEC% /K PowerShell -nologo

This will copy over my profile if it does not exist or is a different version. Now when I am on a server with PowerShell I can double click my batch file and my environment is up to date!