Showing posts with label script. Show all posts
Showing posts with label script. Show all posts

Thursday, January 7, 2021

Retrieving Google Place Data via REST Query to Google API

So my organisation had a need to get accurate latitude and longitude for all of its facilities and had determined that we didn't have a set of accurate records for this.

I determined that we could query Google for this using a web request in the format:


https://maps.googleapis.com/maps/api/place/details/json?placeid=PutYourPlaceIDHere&key=PutYourAPIKeyHere

So, having a list of all of the Google Place IDs for the organisations Google My Business setup, I wrote a little script to invoke a JSON call to Google and pull the latitude and longitude for each facility.

<#
# AUTHOR  : Sean Bradley
# CREATED : 08-01-2021
# UPDATED : 
# COMMENT : Uses Google Maps API Key to grab GMB Data from Web.
# Updates: 
# 1. 
#>
#Establish Logging
$RootPath = "C:\Scripts"
$Logfile = "$RootPath\GetGMBData.Log"
Start-Transcript -path $Logfile
#Establish variables
Write-Host "Setting some variables" -ForegroundColor Green
$InputFile = "$RootPath\GMBPlaceIDs.csv"
$OutputFile = "$RootPath\GMBData.csv"
$MapsKey = "PutYourAPIKeyHere"
$MapsURL = "https://maps.googleapis.com/maps/api/place/details/json?placeid="
Write-Host "Doing some preparatory file checks" -ForegroundColor Gray
$FileExists = Test-Path -Path $OutputFile -PathType leaf
If ($FileExists) {
Write-Host "Deleting last export" -ForegroundColor Gray
Remove-item $OutputFile -force  | Out-Null
}
# Get Input Data from CSV File 
$FileExists = Test-Path -Path $InputFile -PathType Leaf
if ($FileExists) {
Write-Host "Loading $InputFile for processing." 
$tblData = import-csv $InputFile 
}
else {
   Write-Host "$InputFile not found. Stopping script." 
   exit 
}
# Query Google for the required JSON Data
foreach ($row in $tblData)

    Write-Host "Getting Google Data for " $row.'Centre' " with Google Place ID " $row.'PlaceId'

$QueryURL = $MapsURL + $row.'PlaceId' + '&key=' + $MapsKey

$Webdata = Invoke-RestMethod $QueryURL -Method Get |
Select-Object @{Label = "Centre";Expression = {$row.'Centre'}}, 
@{Label = "PlaceID";Expression = {$row.'PlaceId'}},
@{Label = "Lat";Expression = {$_.result.geometry.location.lat}},
@{Label = "Lng";Expression = {$_.result.geometry.location.lng}}|
#Export to CSV
    Export-Csv -Path $OutputFile -NoTypeInformation -Append
}
Stop-Transcript | out-null

Monday, October 31, 2016

How to Stop Windows 10 Domain Computers reporting "Disable apps to help improve performance"

Create or modify a Group Policy Object that applies to the target computers.

Under Computer Configuration\Policies\Windows Settings\Scripts\Startup create a Powershell Script entry named "DisableStartupAppTask.ps1"

In the script, have the single line of code:

Disable-ScheduledTask -TaskName '\Microsoft\Windows\Application Experience\StartupAppTask'



Tuesday, November 25, 2014

Enforce Google Safe Search

So Google is no longer going to permit the nossl DNS trick that previously allowed organisations to disable SSL for searches so that Safe Search could be enforced.

Google Online Security Blog: An update to SafeSearch options for network administrators

The option that they are now permitting is a DNS trick to point users to forcesafesearch.google.com which will still be SSL enabled, but will not allow the user to disable Safe Search.

The only way to ensure this for all Google search engines is to create a DNS zone for each of Googles search domains.... all 193 or so.

Microsoft doesn't let you create a CNAME entry for the parent zone, but it does allow you to create a DNAME entry, so I came up with this script to create all of the zones.

The script, the google.txt file and some basic instructions can be found here.

(I added the length check because the original text file had some carriage returns at the end.)

As always, no responsibility is accepted for its use.

 param([string]$inputfile="google.txt")  
 #Check for the Input file  
 $FileCheck = Test-Path $inputfile  
 if ($FileCheck -eq "True")  
      {  
      write-output "Input file located"  
      }  
 else  
      {  
      write-output "Please supply file containing google zone list"  
      exit  
      }  
 #Process each line in the Input file and create a zone and DNAME record  
 foreach ($zone in Get-Content $inputfile)  
      {  
      $count=$count+1  
      $len = $zone.length -as [int]  
      if ($len -gt 5)  
           {  
           $zone="www"+$zone  
           write-output "Processing entry $($count). Creating zone for $($zone)"  
           dnscmd /zoneadd $zone /dsprimary  
           write-output "Processing entry $($count).Creating DNAME entry for $($zone)"  
           dnscmd /recordadd $zone "@" DNAME forcesafesearch.google.com  
           }  
           else  
           {  
           write-output "Zone data for entry $($count) too short. Not processing."  
           }  
      }  

Resize User Photos and Import them into Active Directory Accounts


Resize User Photos and Import them into Active Directory Accounts using PowerShell and ImageMagick.

This script looks in a specified path for photos named with the EmployeeID attribute of the users in a specified OU, resizes the images to the correct size and then writes the images into the thubnailPhoto attribute of the users Active Directory account.

As always, no responsibility is accepted for it's use.

 param([string]$searchbase , [string]$imagepath)  
 #Import the ActiveDirectory PowerShell module  
 import-module ActiveDirectory  
 #Check for Mandatory Parameters  
 if (!$searchbase)  
      {  
      write-output 'Usage: ADImages {searchbase} {imagepath}'  
      write-output 'eg. ADImages "OU=Staff,OU=Users,DC=orgname,DC=com,DC=au" \\fileserver\Userimages'  
      exit  
      }  
 if (!$imagepath)  
      {  
      write-output 'Usage: ADImages {searchbase} {imagepath}'  
      write-output 'eg. ADImages "OU=Staff,OU=Users,DC=orgname,DC=com,DC=au" \\fileserver\Userimages'  
      exit  
      }  
 #Check if the Searchbase exists  
 $OUCheck = [adsi]::Exists("LDAP://$($searchbase)")  
 if ($OUCheck -eq "True")   
      {  
      write-output "Found Searchbase $($searchbase)"  
      }  
 else  
      {  
      write-output "Searchbase $($searchbase) not found"  
      exit  
      }  
 #Check that the Image Path exists  
 $ImageCheck = Test-Path $imagepath  
 if ($ImageCheck -eq "True")  
      {  
      write-output "Found Image Path $($imagepath)"  
      }  
 else  
      {  
      write-output "Image Path $($imagepath) not found"  
      exit  
      }  
 #Check for the ImageMagick Conversion Tool  
 $ToolCheck = Test-Path ".\ImageMagick\convert.exe"  
 if ($ToolCheck -eq "True")  
      {  
      write-output "ImageMagick tool found"  
      }  
 else  
      {  
      write-output "ImageMagick tool not found. Download from http://www.imagemagick.org/"  
      exit  
      }  
 #Create the Thumbnail directory if it doesn't exist  
 $DirCheck = Test-Path ".\ADThumbs"  
 if ($DirCheck -eq "True")  
      {  
      write-output "Thumbnail directory already exists"  
      }  
 else  
      {  
      write-output "Creating Thumbnail directory"  
      New-Item -ItemType directory -Path .\ADThumbs  
      }  
 #Get an array of users from the Searchbase  
 $UserList = Get-ADUser -Filter * -SearchBase $searchbase  
 Foreach ($User in $UserList)  
      {  
      #Get the EmployeeID Attribute  
      $EmpID = Get-ADUser -Filter * -SearchBase $User -Properties employeeID | select -expand employeeID  
      write-host "Looking for Employee Photo for User $($User) with ID $($EmpID)"  
      #Tests to see if the UserImages file exists  
      $FileCheck = Test-Path "$($imagepath)\$($EmpID).jpg"  
      if ($FileCheck -eq "True")   
           {  
           #Retrieves JPG files of the target user from the UserImages share  
           $jpgfile = "$($imagepath)\$($EmpID).jpg"  
           $newjpgfileName = ".\ADThumbs\$($EmpID)-AD.jpg"  
           write-output "Scaling $($jpgfile) to $($newjpgfileName)"  
           .\ImageMagick\convert $jpgfile -thumbnail 96 -gravity center -crop 96x96+0-15 +repage -strip $newjpgfileName   
           #Write the thumbnail photo back to the AD user Account  
           $photo = [byte[]](Get-Content $newjpgfileName -Encoding byte)  
           Set-ADUser $User -Replace @{thumbnailPhoto=$photo}  
           }  
      else  
           {  
           #User Image file not found  
           write-output "Employee ID $($EmpID) not found in $($imagepath)"  
           }  
      }  

Monday, December 3, 2012

Using ICACLS to Grant Permissions on Folders

It took me a little while to work this out because I found the documentation here a little confusing and multiple interpretations of it seem to be floating around the net.

My goal was to grant a group permissions to access a folder, modify the subfolders and files within it, but not have the ability to modify the folder itself in any way. A pretty common requirement right? You would think some administrator somewhere would have come up with a clear set of instructions on how to do it, but I couldn't find any definitive answer that did quite what I wanted. Eventually, I figured out what I was doing wrong and scripted it myself.

So, the answer is:

icacls "Folder Path" /grant:r "AuthenticationRealm\GroupOrUser":(OI)(CI)(IO)(D,RC,S,AS,GR,GW,GE,RD,WD,AD,REA,WEA,X,DC,RA)

icacls "Folder Path" /grant "AuthenticationRealm\GroupOrUser":(RC,S,AS,GR,GE,RD,WD,AD,REA,X,DC,RA)

The first command replaces [/grant:r] any existing permissions for the GroupOrUser on all Subfolders and files only of the Folder Path and all of it's contents that inherit [(OI)(CI)(IO)] without forcing inheritance, and grants everything except Change permissions and Take ownership rights.

The second command grants GroupOrUser permissions to the Folder Path itself, but grants only those permissions that allow the GroupOrUser to be able to create files/folders and write data. They are not able to delete or modify the folder.

The permissions list in the first command can be modified to give Read Only access or Write Only (Dropbox) style access. If you're doing dropbox style access, it's sometimes a good idea to give the special identity CREATOR OWNER extra permissions so that submitters can modify their own work and it can also be a good idea to use Access-based Enumeration so that submitters cannot see other users submissions that may be in the same share.

There's probably a better way to do this in Powershell, but I haven't discovered it yet.




Thursday, September 30, 2010

Reset Passwords for all User Accounts in an OU

I realise that there's plenty of scripts floating around the net that already do this, but for me this was simply an exercise.

Note: I haven't gotten around to testing it yet.


' PasswordReset.vbs
' Resets all passwords within an AD Container
' Version 1.0
' 27 September 2010


Option Explicit
Dim objRootDSE, objOU, objUser
Dim strTargetOU, strForceReset, strEnAcct, strDNSDomain, strNewPass
Dim intCounter, intUACval, intPWLval


' Change strTargetOU to location of user accounts
strTargetOU = "MyContainer"


' Change strNewPass to the new password
strNewPass = "Password123"


' Change strForceReset to "Yes" in order to force users to reset passwords
strForceReset = "No"


' Change strEnAcct to "Yes" in order to enable disabled accounts
strEnAcct = "No"


' Int Values 
' See Microsoft KB305144 for UserAccountControl values
' Setting PwdLastSet value to 0 forces password reset
intUACval = 544
intPWLval = 0
intCounter = 0


Set objRootDSE = GetObject("LDAP://RootDSE") 
strDNSDomain = objRootDSE.Get("DefaultNamingContext")
strTargetOU = "OU=" & strTargetOU & ", " & strDNSDomain
set objOU =GetObject("LDAP://" & strTargetOU )


For each objUser in objOU
If objUser.class="user" then
objUser.SetPassword strNewPass
objUser.SetInfo


If strForceReset="Yes"
objUser.Put "pwdLastSet", intPWLval
objUser.SetInfo
End if
If strEnAcct="Yes"
objUser.Put "userAccountControl", intUACval
objUser.SetInfo
End if


intCounter = intCounter +1
End if
Next


WScript.Echo "New Password: " & strNewPass & vbCr & "Accounts changed: " & intCounter _
  & vbCr & "Password Change Forced: " & strForceReset & vbCr & "Disabled Accounts Enabled: " & strEnAcct
  


Thursday, August 12, 2010

Subroutine to quit a VBS login script on Windows 2003/2008 servers

Sub DetectOS()

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colOperatingSystems = objWMIService.ExecQuery _
    ("Select * from Win32_OperatingSystem")

    For Each objOperatingSystem In colOperatingSystems
        If InStr( objOperatingSystem.Caption,"2003") <> 0 _
        or InStr( objOperatingSystem.Caption,"2008") <> 0  Then
            WriteLog "Detected Operating System: " & objOperatingSystem.Caption
                WriteLog "Script will not continue...."
            WScript.Quit(0)
        Else
                WriteLog "Detected Operating System: " & objOperatingSystem.Caption
                WriteLog "Script will continue....."
        End if
    NextEnd Sub

Sunday, July 4, 2010

Locating Encrypted Files

When undertaking a file migration project between Active Directory domains and forests, it's necessary to locate any EFS encrypted files in order to decrypt them prior to the decommissioning of the old domain and the loss of the keys.

I located this handy script that will identify encrypted files in a volume (just change the drive letter as necessary):

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
     & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colFolders = objWMIService. _
     ExecQuery("Select * from Win32_Directory where Drive='C:'" _
              & " AND Encrypted=True")

For Each objFolder in colFolders
     Wscript.Echo "Name: " & objFolder.Name
     Wscript.Echo "Path: " & objFolder.Path
Next

Thursday, May 13, 2010

Change the READY message on HP Printers

A little bit of Friday humour...

Be aware that this may be against your organisations Acceptable Use Policy. Also be aware that people without a sense of humour may not find it funny. Don't get into trouble!

The message may be reset to the default by power cycling the printer, or re-running the script and passing "READY" as the message.

Please note, I have not tested this... yet... hehehe.


Telnet to port 9100 on the printer and enter the following: 

\e%-12345X\@PJL JOB
\@PJL RDYMSG DISPLAY="MESSAGE HERE"
\@PJL EOJ
\e%-12345X

Some funny suggestions:
“Insert Coin”,
“Insert Cheese”,
“Im Sad..”,
“Low Monkeys”,
“Feed me a cat”,
“Insert Butter & Jam”,
“Free The Ink!!”,
“My Cousin Is A Toaster”,
“Load Soy Latte”,
“Paper Tastes Funny Today”,
“Free Hugs..”,
“Toner Tastes Funny Today”,
“Press OK Button for Pacman”,
“Flower Power Mode”,
“Incoming Fax…”,
“Cheese Mode”




Thursday, January 28, 2010

Move and Disable Stale Computer Accounts

I started to write a script today to relocate and disable computer accounts that have an old PwdLastSet attribute. Before I got very far, I discovered that Richard Mueller of Hilltop Lab had already done quite an effective job of scripting this very task and has made the effort to refine it a few times too.

The script can be found at http://www.rlmueller.net/Programs/MoveOldComputers.txt

I modified it a little to suit my own purposes, but his script certainly got me 90% of the way there. Thanks for saving me the effort Richard!

Cheers,
Sean

Wednesday, January 20, 2010

Windows Update Problem Fixup Script

I've had this script floating around for a while. I put it together based on a number of recommendations from Microsoft regarding fixing problems with Windows Update.

Note that this will fix some errors, but there are a whole swag of issues that can arise with automatic updates.

Also, as always, I take absolutely no responsibility if this causes your machine to implode (although I would love to see the photos if it does!)

@echo off

if exist %systemroot%\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\tmp*.cat del /F /Q %systemroot%\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\tmp*.cat


if exist %systemroot%\system32\CatRoot\{127D0A1D-4EF2-11D1-8608-00C04FC295EE}\tmp*.cat del /F /Q %systemroot%\system32\CatRoot\{127D0A1D-4EF2-11D1-8608-00C04FC295EE}\tmp*.cat

if exist %systemroot%\System32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\kb*.cat del /F /Q %systemroot%\System32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\kb*.cat

if exist %systemroot%\System32\CatRoot\{127D0A1D-4EF2-11D1-8608-00C04FC295EE}\kb*.cat del /F /Q %systemroot%\System32\CatRoot\{127D0A1D-4EF2-11D1-8608-00C04FC295EE}\kb*.cat

regsvr32 /s softpub.dll

regsvr32 /s wintrust.dll
regsvr32 /s initpki.dll
regsvr32 /s dssenh.dll
regsvr32 /s rsaenh.dll
regsvr32 /s gpkcsp.dll
regsvr32 /s sccbase.dll
regsvr32 /s slbcsp.dll
regsvr32 /s mssip32.dll
regsvr32 /s cryptdlg.dll

attrib -s -h %windir%
attrib -s -h %windir%\system32
attrib -s -h %windir%\system32\catroot2

net stop cryptsvc
ren %systemroot%\System32\Catroot2 oldcatroot2
net start cryptsvc

net stop wuauserv
rd /S /Q %windir%\SoftwareDistribution
md %windir%\SoftwareDistribution
net start wuauserv

Cheers,
Sean

Sunday, November 15, 2009

Local Account Manipulation

I had a request the other day from someone who knows some of my work. He had seen my scripts for manipulating local accounts on machines but couldn't make sense of them. (This was essentially because he was only seeing half of the system.) He asked if I could explain them in my blog, so here goes...

There are many different methods for manipulating local accounts on machines. Some companies make a profit from selling software that will go and talk to all of the machines and change passwords, accounts, group memberships, etc. Surprisingly, Microsoft has not yet integrated any system for easy management of local computer accounts into their own domain management systems. (Edit: Of course Microsoft has finally done something about this and you can now use Group Policy Preferences to manage local accounts quite easily. I thoroughly recommend using Group Policy instead of the method described here!)

Anyway, one way to achieve this is to use the Group Policy system. Computers run the Computer Startup Scripts with system administrative rights (Computer Configuration / Windows Settings / Scripts / Startup.) This enables the savvy administrator to run a script that can be used to manipulate local accounts.

What about the fact that the passwords may be exposed in the script? Some administrators will suggest that you do it in VBScript and then encrypt it. This is not a good idea because it is far too easy to decrypt these files. IMHO, it is much better to let Microsofts domain security protect it for you. (I can't believe I just said that. Scary but true!)

You can place these 'scriptlets' below in your scripts folder and pass the required parameters to them from your GPO. You secure your GPO by removing Authenticated Users from having read and apply group policies rights and giving Domain Computers read and apply group policy rights. Using this method, the users cannot see the new passwords, but the computers which are running the scripts can.

There is a caveat. The computers have to be processing group policies in order to run the scripts. This may be prevented by slow link detection, the behaviour of which can be modified. It may also not be processed by computers coming into the network by remote access. A user logging into the computer by remote access can process the scripts, but a user logging into your VPN or dial-up after logging in the computer using cached credentials will not process the scripts.

IDCHPASS.BAT: Used to Change a local user identity password.

@ECHO OFF
REM USAGE: IDCHPASS username newpassword
NET USER %1 %2

IDCREATE.BAT: Used to create a local identity.
@ECHO OFF
REM USAGE: IDCREATE username password
NET USER %1 %2 /ADD

IDDELETE.BAT: Used to delete a local identity.

@ECHO OFF
REM USAGE: IDDELETE username
NET USER %1 /DELETE
IDENABLE.BAT: Used to enable or disable a local identity.

@ECHO OFF
REM USAGE: IDENABLE username YES\NO
NET USER %1 /ACTIVE:%2

IDGROUP.BAT: Used to change the group membership of a local identity, or to create or delete local groups.

@ECHO OFF
REM USAGE: IDGROUP group ADD\DELETE username
REM USERNAME IS ADDED TO OR DELETED FROM GROUP
REM USERNAME CAN BE LEFT OFF TO ADD OR DELETE GROUPS
NET LOCALGROUP %1 %3 /%2


A shoutout goes to ripvankip for giving me something to write about! ;)

Sean

Thursday, September 10, 2009

How to Edit an INI file using VBScript

Modify the highlighted sections with the appropriate changes.

Note that you can use environment variables to ensure that it will work on all systems. eg. If you use %SystemRoot% it will work whether windows is installed in C:\WINNT or D:\Windows.


' This script can be used to edit entries in ini files
'
' Written by Sean Bradley
' Version 1.0
' Last modified 11/09/09
'
Const ForReading = 1
Const ForWriting = 2
Set oShell = CreateObject( "WScript.Shell" )

'Set the target file and backup directory.
'Note that I've used an environment variable here to ensure it works on all systems.
'
targfile=oShell.ExpandEnvironmentStrings("%SystemRoot%") + "\editthisfile.ini"
backdir=oShell.ExpandEnvironmentStrings("%TEMP%") + "\"
Set objFSO = CreateObject("Scripting.FileSystemObject")

'Make sure the file exists to prevent errors.
'
if objFSO.FileExists(targfile) then
'Copy it to the backup directory then open the file.
objFSO.CopyFile targfile, backdir, true
Set objTextFile = objFSO.OpenTextFile(targfile, ForReading)

'Read through each line of the file for the entry you want to set
'
Do Until objTextFile.AtEndOfStream
strNextLine = objTextFile.Readline
intLineFinder = InStr(strNextLine, "IniFileEntrytoEdit")
If intLineFinder <> 0 Then

'Set your new entry here.
'
strNextLine = "IniFileEntrytoEdit=My Entry in the File"
End If
strNewFile = strNewFile & strNextLine & vbCrLf
Loop

objTextFile.Close

'Write the file with the new entry
'
Set objTextFile = objFSO.OpenTextFile(targfile, ForWriting)

objTextFile.WriteLine strNewFile
objTextFile.Close
End If

Monday, August 17, 2009

Log File Cleanup

I needed a tool to clean up log files that exceed a certain age and I remembered a simple executable that I used to have called deleteifolderthan.exe that did just what was required, but when I went looking for it, I couldn't locate it anywhere.

Giving up on that, I decided to write my own script. I needed something that would delete log files over a month old in subdirectories of a parent directory. This is what I came up with:

Const ParentFolder = "E:\Logs"
Const MaxDays = 31
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(ParentFolder)
Set colSubFolders = objFolder.SubFolders
For Each objDir in colSubFolders
Set colFiles = objDir.Files
For Each objFile in colFiles
If DateDiff("d",objFile.DateCreated,now) >= MaxDays Then
objFSO.DeleteFile(objFile.Path)
End If
Next
Next


If you wanted to delete old logs in a single folder, you could simplify this to:

Const WatchFolder = "E:\Logs"
Const MaxDays = 31
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objDir = objFSO.GetFolder(WatchFolder)
Set colFiles = objDir.Files
For Each objFile in colFiles
If DateDiff("d",objFile.DateCreated,now) >= MaxDays Then
objFSO.DeleteFile(objFile.Path)
End If
Next


Cheers,
Sean

Tuesday, April 28, 2009

WSUS: Clients overwriting each other


I discovered an interesting issue recently where a number of machines that were clones of each other were using the same IDs to report to WSUS and were therefore constantly overwriting each other in the WSUS database.

A quick run of this script against the machines was able to force a change of those IDs and set a registry entry flag so that if the script were run again (such as from a computer startup GPO), it wouldn't reset the IDs again.


Set oShell = CreateObject("WScript.Shell")

sRegKey = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate"

' suppress error in case values does not exist
On Error Resume Next

' check for marker

sIDDeleted = oShell.RegRead( sRegKey & "\IDDeleted")

' to be sure values is only deleted once, test on marker
If sIDDeleted <> "yes" Then
' delete values
oShell.RegDelete sRegKey & "\AccountDomainSid"
oShell.RegDelete sRegKey & "\PingID"
oShell.RegDelete sRegKey & "\SusClientId"

' Stop and start the Automatic updates service
oShell.Run "%SystemRoot%\system32\net.exe stop wuauserv", 0, True
oShell.Run "%SystemRoot%\system32\net.exe start wuauserv", 0, True

' Run wuauclt.exe with resetauthorizations
Cmd = "%SystemRoot%\system32\wuauclt.exe /resetauthorization /detectnow"
oShell.Run sCmd, 0, True

' create marker
oShell.RegWrite sRegKey & "\IDDeleted", "yes"
End If


We actually chose to run the script on the target machines using SCHTASKS.EXE from the Support Tools. I created a text file containing the names of all of the target machines and simply ran this script:

@echo off
FOR /F %%i IN (WSUS_Fix_Targs.txt) DO (
schtasks /create /tn "%%i_WSUS_SID_Fix" /tr "wscript.exe \\server\share\WSUS_Fix.vbs" /sc once /st 15:00 /ru domain\adminuser /rp userpassword /z /s %%i
)

Thursday, March 5, 2009

SCCM: Distribution Points


It seems that if a Distribution Point in the SCCM distribution model exceeds its configured retries, it doesn't appear to run a maintenance task in order to get those packages. The maintenance task essentially checks what packages the server is meant to have against the packages it finds already on the disk. (You can copy the files in there manually and it will be quite happy).

In order to force the Distribution Points to run a maintenance task, I acquired this handy little script from Microsoft and have scheduled it to run nightly against a collection of machines that has the Distribution Point role. Sit back and you can watch the network activity jump at the scheduled time.


' Set required variables.
actionNameToRun = "Peer DP Maintenance Task"

' Create a CPAppletMgr instance.
Set controlPanelAppletManager = CreateObject("CPApplet.CPAppletMgr")

' Get the available ClientActions object.Set availableClientActions = controlPanelAppletManager.GetClientActions()

' Loop through the available client actions. Run matching client action when found.
For Each clientAction In availableClientActions
If clientAction.Name = actionNameToRun Then
clientAction.PerformAction
wscript.echo "Ran: " & clientAction.Name
End If
Next