Wednesday 25 February 2015

Linux: Creating undeletable file that users can read/write to

Hey all,

Came across an interesting question today. Basically they wanted to create a file that a user could read/write to but not delete the file. I have a simple solution to this!! Using the "Restricted Delete Flag" of chmod when applied to a folder. Basically by creating a folder and enabling the "Restricted Delete Flag" on the folder allows users the permissions within the folder assigned to the specific files, however users with write access to a file cannot delete it. (Only the original user can delete it)
Any way here was/is my solution that will allow a user rw access to a file but be unable to delete it.

First create a folder: mkdir newfolder
Then set the restricted deletion flag on the folder: chmod 1705 newfolder/
Then in the folder create your new file
touch file
Set permissions: chmod 600 file
Then grant the user access: setfacl -m u:theuser:rw file

When you check the permissions using getfacl it should look something like this:
[root@ripper folder]# getfacl file
# file: file
# owner: root
# group: root
user::rw-
user:theuser:rw-
group::r--
mask::rw-
other::---

[root@ripper theuser]# getfacl folder
# file: folder
# owner: root
# group: root
# flags: --t
user::rwx
group::---
other::r-x


Now if you test your user can write to the file but will be unable to delete the file..
[theuser@ripper folder]$ cat file
[
theuser@ripper folder]$ echo testing | tee -a file
testing
[
theuser@ripper folder]$ cat file
testing
[
theuser@ripper folder]$ rm file
rm: cannot remove ‘file’: Permission denied
[
theuser@ripper folder]$ ls -alh file
-rw-rw----+ 1 root root 8 Feb 25 21:39 file
 

Much yays. Comments below if you have any other interesting ways of doing this.. Or if you get stuck doing this :)

Tuesday 24 February 2015

USMT Between Windows XP and Windows 8.1

Hey!

Becuase things always like to run smoothly and as painless as possible for us people in IT.... If you happen to be lucky enough to try get USMT working between XP and Win8.1 you will find that "shit just don't work". USMT 5 which works on XP does not work on Win 8.1, likewise USMT 6.3 does not work on XP.. ffs you say. Well don't worry I hacked up some hard work for you.

Just chuck USMT src in some location and this script will run the correct version for you.. YAY! (YOU NEED TO FIX THE SCRIPT TO YOUR ENVIRONMENT FIRST!!!!!!!)

FYI if you have no idea what the script is doing then just ask, if you know what it is doing then I hope you know how to fix it for your own environment.. If not just ask. I am feeling lazy and don't feel like explaining this at the moment(eg time of writing) :)

Either way I hope it gives people an idea to make things slightly easier

Option Explicit
Public Const WindowHidden = 0
Public Const ForReading = 1
Public Const ForWriting = 2
Public Const ForAppending = 8
Dim objShell: Set objShell = CreateObject("WScript.Shell")
Dim objFSO: Set objFSO = CreateObject("Scripting.FilesystemObject")
Dim strThisComputer: strThisComputer = objShell.ExpandEnvironmentStrings("%ComputerName%")
Dim strMigBasePath: strMigBasePath = "c:\MIG"
Dim cMD, iRes
Dim intBit
Dim strDestComputer
Dim strComputer: strComputer = "."
Dim objWMI, colOperatingSystems
Dim i, strOSVer, f, bHLink
Dim strUSMTSrc: strUSMTSrc = "c:\USMTSTUFF"
Dim strStorePath: strStorePath = "\USMT"
Dim strDestFile: strDestFile = "c:\dest.txt"
Dim strDExist: strDExist = False
Dim strMode
bHLink = False 'default to no hardlink
GetArgs()
If strMode = "SCAN" Then
'run scanstate tasks
wscript.echo "Running ScanState tasks"
ChkPath(strMigBasePath)
ChkOSVer()
GetUSMTSrc()
ChkDestAlive()
RunScanState()
Else
'run loadstate tasks
wscript.echo "Running LoadState tasks"
ChkPath(strMigBasePath)
ChkPath("c:"&strStorePath)
SharePath()
ChkOSVer()
GetUSMTSrc()
ChkDrive()
RunLoadState()
End If
'will only get this far if successful
wscript.echo "SUCCESSFULLY COMPLETED"
Wscript.quit(0)
Sub GetArgs()
Dim colNamedArgs
strMode = "NA"
Set colNamedArgs = WScript.Arguments.Named
If colNamedArgs.Exists(UCase("MODE")) Then
Select Case UCase(colNamedArgs.Item(UCase("MODE")))
Case "SCAN"
strMode = "SCAN"
Case "LOAD"
strMode = "LOAD"
Case Else
strMode = "NA"
End Select
End If
If strMode = "NA" Then
WScript.Echo "/Mode not defined"
WScript.Quit(-99)
End If
End Sub
Sub SharePath()
cMD = "net share usmt=c:\usmt /GRANT:Everyone,FULL"
iRes = objShell.Run(cMD, WindowHidden, True)
If iRes <> 0 Then
wscript.echo "Error creating share: " & iRes
wscript.quit(-1)
Else
wscript.echo "SUCCESS creating USMT share!"
End If
cMD = "Icacls c:\usmt /grant Everyone:F /inheritance:e /T"
iRes = objShell.Run(cMD, WindowHidden, True)
If iRes <> 0 Then
wscript.echo "Error fixing share permissions: " & iRes
wscript.quit(-1)
Else
wscript.echo "SUCCESS fixing share permissions!"
End If
End Sub
Sub ChkOSVer()
'get OS version
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMI.ExecQuery("Select * from Win32_OperatingSystem")
For Each i in colOperatingSystems
strOSVer = i.Version
Next
Select Case Mid(strOSVer,1,3)
Case "5.1"
strOSVer = "XP"
strUSMTSrc = strUSMTSrc & "\USMT5"
Case "6.1"
strOSVer = "7"
strUSMTSrc = strUSMTSrc & "\USMT6.3"
Case "6.2"
strOSVer = "8"
strUSMTSrc = strUSMTSrc & "\USMT6.3"
Case "6.3"
strOSVer = "8.1"
strUSMTSrc = strUSMTSrc & "\USMT6.3"
Case Else
'dont know about you
wscript.echo "ERROR UNKNOWN OS"
Wscript.Quit(-1)
End Select
'What Arch are we running 32 or 64bit?
intBit = GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth
If intBit = 32 Then
'build 32bit path to USMT
strUSMTSrc = strUSMTSrc & "\x86\"
Else
'build 64bit path to USMT
strUSMTSrc = strUSMTSrc & "\amd64\"
End If
End Sub
Sub GetUSMTSrc()
'Get the files
cMD = "xcopy.exe """ & strUSMTSrc & "*.*"" " & strMigBasePath & "\ /s /y"
iRes = objShell.Run (cMD, WindowHidden, True)
If iRes <> 0 Then
Wscript.Echo "Error moving USMT files"
WScript.Quit(-1)
End If
'move the xml templates that drive scanstate
cMD = "xcopy.exe """ & strUSMTSrc & "\..\..\conf\*.*"" " & strMigBasePath & "\ /s /y"
iRes = objShell.Run (cMD, WindowHidden, True)
If iRes <> 0 Then
Wscript.Echo "Error moving USMT xml"
WScript.Quit(-1)
End If
End Sub
Sub ChkDestAlive()
'find the dest computer
If Not objFSO.FileExists(strDestFile) Then
strDestComputer = Inputbox("Please enter the destination computername","Input Required")
If strDestComputer = "" Then
'no input detected
wscript.echo "No destination computer defined. Quiting"
WScript.Quit(-1)
End If
Else
Set f = objFSO.OpenTextFile(strDestFile, FORREADING)
strDestComputer = f.ReadLine
f.Close
End If
strStorePath = "\\" & strDestComputer & strStorePath
If UCase(strDestComputer) = "LOCALHOST" Or UCase(strDestComputer) = UCase(strThisComputer) Then
'assume we want a hardlink
bHLink = True
Else
'make sure we can connect to the dest
Set f = objFSO.CreateTextFile("c:\chkdest.txt",True)
f.Write "check" & vbCrLf
f.Close
cMD = "xcopy.exe c:\chkdest.txt " & strStorePath & "\ /y"
iRes = objShell.Run(cMD, WindowHidden, True)
If iRes <> 0 Then
wscript.echo "Error connecting to destination computer"
Wscript.Quit(-1)
End If
End If
End Sub
Sub RunScanState()
'Build USMT scanstate
cMD = strMigBasePath & "\scanstate.exe" & " " & strStorePath &_
" /o" &_
" /ue:" & strThisComputer & "\Administrator" &_
" /ue:" & strThisComputer & "\Admin" &_
" /UEL:365" &_
" /Config:c:\mig\config.xml" &_
" /i:c:\mig\Mig.xml" &_
" /i:c:\mig\MigApp.xml" &_
" /i:c:\mig\MigDocs.xml" &_
" /i:c:\mig\MigUser.xml" &_
" /v:13 /l:c:\scanstate.log"
If bHLink Then cMD = cMD & " /hardlink /nocompress"
iRes = objShell.Run(cMD, WindowHidden, True)
If iRes <> 0 Then
wscript.echo "Error Received running scanstate: " & iRes
wscript.quit(-1)
Else
wscript.echo "SUCCESS!"
End If
'copy the scanstate log so the dest knows it can restore
cMD = "xcopy.exe c:\scanstate.log " & strStorePath & "\ /y"
iRes = objShell.Run(cMD, WindowHidden, True)
If iRes <> 0 Then
wscript.echo "Error connecting to destination computer"
Wscript.Quit(-1)
End If
If bHLink Then
'put a file so loadstate knows it is a hardlink
Set f = objFSO.CreateTextFile("c:\usmt\HARDLINK.txt",True)
f.Write "HARDLINK" & vbCrLf
f.Close
End If
End Sub
Sub RunLoadState()
'Build USMT loadstate
Dim intSleep: intSleep = 120 * 1000 '120 seconds.. * 1000 is because it is in ms..
Dim strScanStateLoc: strScanStateLoc = "c:\usmt\scanstate.log"
Dim strMigXML: strMigXML = "c:\mig\Mig.xml"
'pre check to see if this is a hardlink store
If objFSO.FileExists("c:\usmt\HARDLINK.txt") Then
'we are restoring from a hardlink
bHLink = True
End If
cMD = strMigBasePath & "\loadstate.exe C:\usmt" &_
" /ue:" & strThisComputer & "\Administrator" &_
" /ue:" & strThisComputer & "\Admin" &_
" /i:" & strMigXML &_
" /i:c:\mig\MigApp.xml" &_
" /i:c:\mig\MigDocs.xml" &_
" /i:c:\mig\MigUser.xml" &_
" /v:13 /l:c:\loadstate.log"
If bHLink Then cMD = cMD & " /hardlink /nocompress"
wscript.echo cMD
'make sure the scanstate.log exists
Do While Not objFSO.FileExists(strScanStateLoc)
wscript.echo "Waiting for scanstate...."
wscript.sleep intSleep
Loop
iRes = objShell.Run(cMD, WindowHidden, True)
If iRes <> 0 Then
wscript.echo "Error Received running loadstate: " & iRes
wscript.quit(-1)
Else
wscript.echo "SUCCESS!"
End If
End Sub
Sub ChkDrive()
If objFSO.DriveExists("D:") Then
strDExist = True
End If
End Sub
Function ChkPath(thePath)
'does path exist
If Not objFSO.FolderExists(thePath) Then
Dim aTemp, d, p
'build path
aTemp = split(thePath,InStrRev(thePath,"\"))
p = ""
For Each d in aTemp
If p <> "" Then p = p & "\"
p = p&d
If Not objFSO.FolderExists(p) Then objFSO.CreateFolder(p)
Next
End If

Monday 9 June 2014

Linux: A+ Certification ssllabs certificate configuration for your apache website (Updated 15 June 2015)

Hi Guys,


NOTE: This has been updated on 15 June 2015 to include use of sha256 and sha256 startcom intermediate cross signing certificate. This will still give you an A+ rating.

Here is a quick configuration to use allowing A+ certification for your apache webserver.
NOTE: In order for ECDHE to work you MUST be using apache2.4 or greater(see here)
First goto your apache conf dir (/etc/apache2/)
create an ssl directory if it does not exist
mkdir ssl
cd ssl

If you have multiple vhosts it is a good idea to separate your certificates
mkdir vhostname
cd vhostname

now generate your CSR we will use to request our certificate
openssl req -sha256 -out vhostname.csr -new -newkey rsa:4096 -nodes -keyout vhostname.key
This will generate a 4096bit RSA CSR we will use for the next step.
Copy the content of the vhostname.csr

Goto the following website:
StartSSL
Goto the validation wizard and generate a domain validation for your domain

Once you have received your validation email and entered the key go back to the certificate wizard tab
Select "Web Server SSL/TLS Certificate"
Skip the generate private key section (we created ours just before)
Paste in the content from your vhostname.csr
Create your subdomain to generate and add a SAN (eg www.vhosthostname)

Once your key has been generated create a new file "vhostname.crt" in your vhostname directory
now download the StartSSL certificate as we need to add it later in our virtualhost
wget https://www.startssl.com/certs/class1/sha2/pem/sub.class1.server.sha2.ca.pem -O sub.class1.server.ca.pem

Secure your keys

chmod 400 *

goto your vhost configuration
(somewhere in /etc/apache2/sites-enabled/)
default is 000-default however I usually create one per site im hosting

Here is an extract:
<virtualhost *:80>
 ServerAdmin webmaster@vhostname.com
 ServerName www.vhostname.com
 ServerAlias vhostname.com
 Redirect permanent / https://www.vhostname.com
</VirtualHost>

<virtualhost *:443>
 ServerAdmin webmaster@vhostname.com
 ServerName www.vhostname.com

 Header always set Strict-Transport-Security "max-age=163072000; includeSubDomains"

 DocumentRoot /var/www/vhostname
 <directory />
  Options FollowSymLinks
  AllowOverride None
 </Directory>
 <directory /var/www/vhostname>
  Options Indexes FollowSymLinks MultiViews
  AllowOverride None
  Order allow,deny
  allow from all
 </Directory>

 ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
 <directory "/usr/lib/cgi-bin">
  AllowOverride None
  Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
  Order allow,deny
  Allow from all
 </Directory>

 ErrorLog ${APACHE_LOG_DIR}/error_vhostname.log

 # Possible values include: debug, info, notice, warn, error, crit,
 # alert, emerg.
 LogLevel warn

 CustomLog ${APACHE_LOG_DIR}/access_vhostname.log combined

 SSLEngine on
 SSLProtocol all -SSLv2 -SSLv3
 SSLHonorCipherOrder on
 SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4
 SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
 SSLCertificateFile /etc/apache2/ssl/vhostname/www.vhostname.com.crt
 SSLCertificateKeyFile /etc/apache2/ssl/vhostname/www.vhostname.com.key
 SSLCertificateChainFile /etc/apache2/ssl/vhostname/sub.class1.server.ca.pem
</VirtualHost>
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLCACertificateFile /etc/apache2/ssl/vhostname/sub.class1.server.ca.pem
SSLStaplingCache shmcb:/var/run/ocsp(128000)

We can see here we have a perm redirect from the HTTP site to the HTTPS site.
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains" will force the browser from now on to connect ONLY via HTTPS

We turn on the SSLEngine
We disable SSLv2 and v3(not secure)
We force the ciphers to be honored in the order listed(eg to use the strongest possible
We set the CipherSuite (This method only allows AES-265 which can disable java from working. In this case use the following:
SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4
The SetEnvIf protects server side against an attack known as BEAST
We then set our certificates

Outside of the VirtualHost tag we set OCSP stapling which stops the clients going to check OSCP every request(speeds up processing keeping it server side).

Now restart apache (service apache2 restart) and you should be good to go. Check out your score on https://www.ssllabs.com

Let me know how you get on down below in the comments. Obviously I have written this very "quickly" and it requires some knowledge of linux and openssl. Using this configuration gives me the following:

Sunday 8 June 2014

Linux: Upgrading apache 2.2 to apache 2.4

Hi All,

If you are looking at upgrading apache 2.2 to apache 2.4 here is a quick guide for you (tested ubuntu 12.04 LTS)

First you need to add some repos
apt-add-repository ppa:ptn107/apache
apt-add-repository ppa:ondrej/php5

Then quickly do an update

apt-get update

Once this is complete install the upgraded 2.4.9(at time of writing)
apt-get install apache2-mpm-worker

Accept any updates to other packages and continue with the upgrade.

FYI

If you are using vhosts when you are hosting multiple sites from apache 2.4 they seemed to have changed the include in apache2.conf (located in /etc/apache2/)

If your vhosts are not working the include now looks for sites-enabled/*.conf in the apache2.conf
just edit as follows:
OLD: IncludeOptional sites-enabled/*.conf
NEW: IncludeOptional sites-enabled/*

then restart apache2
service apache2 restart

now your vhosts should be working again :)

Next guide "Getting A+ rating on globalsign sslchecker using free!!!11!!! certificates :)"

Sunday 25 May 2014

Python: Restarting and monitoring specific threads

Hi All,

Anyone who has used python before knows how painful threading can be. Especially if we have a multithreaded program that we require specific threads to "always" be alive.
Having hacked around for awhile I came up with the following solution:

import threading
import time

class ThreadRestartable(threading.Thread):
def __init__(self, theName):
threading.Thread.__init__(self, name=theName)

def run(self):
print "In ThreadRestartable\n"
time.sleep(10)

thd = ThreadRestartable("WORKER")
thd.start()

while(1):
i = 0
for t in threading.enumerate():
if t.name is "WORKER":
i = 1
print threading.enumerate()
if i == 0:
thd = ThreadRestartable("WORKER")
thd.start()
time.sleep(5)
We can see it running here:
python run.py
In ThreadRestartable
[<_MainThread(MainThread, started 139833484474176)>, ]

[<_MainThread(MainThread, started 139833484474176)>, ]
[<_MainThread(MainThread, started 139833484474176)>, ]
[<_MainThread(MainThread, started 139833484474176)>, ]
[<_MainThread(MainThread, started 139833484474176)>, ]
[<_MainThread(MainThread, started 139833484474176)>]
[<_MainThread(MainThread, started 139833484474176)>]
In ThreadRestartable

[<_MainThread(MainThread, started 139833484474176)>, ]
[<_MainThread(MainThread, started 139833484474176)>, ]

As we can see we use a named thread WORKER where we then use threading.enumerate() to look for the thread we named. If it does not exist we start it again. This would normally be used in a situation where we have a long running thread that should never end. In which case if you use the standard way of creating a thread then watch it with something like if not thread.IsAlive() and try to call start() on it again you will find python raises an assertion error. This is because the threading object needs to be recreated.
Hope this helps someone out there :)

Thursday 22 May 2014

SCOM 2012 R2: Linux Monitoring...

Hi Guys,

It has been a really long time since I posted on here but yes I am still around heh :)

Anyway I have been working with a client lately who wants to checkout the linux monitoring from SCOM, of which I have personally stayed away from (I have a unix/linux background I am paranoid to put anything MS on something like RHEL). Anyway since the client wants to get rid of the other monitoring platforms on place if possible and have all monitoring coming from one system I had no choice but to check it out.

At first most of the issues around deploying the agent happened to be with the RHEL box one of the unix guys gave me. Basically some firewall fun and adding the SCOM IP's into /etc/hosts.allow, after this I could discover the box but the install was failing at the certificate assignment. In this case it turns out I forgot to set the certificate profile run as account back in SCOM. After setting this the agent installed fine... Next I was not actually getting any performance monitoring in the console, then realizing I forgot to assign the run as profile for the unprivileged and privileged users woohoo..

So I eventually figured it out but then couldn't be bothered waiting for it to pull data so went home..

Will update you all as to if you should even bother with the linux based monitoring agents I'm guessing not :)

6/6/14 UPDATE:
So far the servers have not died which is a good thing I guess. The base RHEL pack obviously is pulling in all the std happy crap like disk usage etc other that that nothing special. I did try a bunch of management packs from an "un-named" company for MySql and Apache(httpd). I don't really have very good things to say about them I may name drop them in future :D

Wednesday 30 May 2012

SCCM: Package returning error 259 how-to resolve

After attempting to deploy namely "AutoDesk" to an environment, we came across an issue where the SCCM Advertisement was returning error 259 in the CAS logs on clients. After investigations it was found that setup.exe was executing then spawning other processes while the setup thread was killed. Hence the agent was misreporting the install even though it was eventually successful. This is a small script I wrote to be executed via the program in the package for installs such as this. You must change the:
-strLogLoc (To the actual msi installer log to be monitored)
-cMD (To the actual installer command line)
-The if InStr check for the text in the log that is displayed with the main thread exit code(should be right at the end of the log) in this instance for AutoDesk I have used "]: MainEngineThread is returning" when it parses this line and grabs the "last" character of the line(the error code in this instance)


Don't attempt to modify the script other than this if you are not sure what you are doing, however feel free to ask a question and I shall reply when I have time. Hope this helps people google tells me alot of people have not been able to resolve this.


Sean

On Error Resume Next
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = WScript.CreateObject("WScript.Shell")


strCmd = objShell.ExpandEnvironmentStrings("%comspec%")


strScriptPath = objFSO.GetParentFolderName(wscript.ScriptFullName)
strLogLoc = "c:\Windows\Temp\Autodesk Revit Architecture 2012 Install (en-us).log"
'wscript.echo strScriptPath
If not right(strScriptPath,1) = "\" Then
strScriptPath = strScriptPath & "\"
End If
'wscript.echo strScriptPath




cMD = strCmd & " /c " & strScriptPath & "\Image\Setup.exe /qb /I Image\AutoDeskRevit_20.12_86a.ini"
'wscript.echo strCmd
'wscript.echo cMD
'Return = objShell.Run(cMD,0,False)


'Loop to wait for the log to be created to we check to see when it is finished installing
bLogExist = 1
While bLogExist = 1
    If objFSO.FileExists(strLogLoc) Then
wscript.echo "log exists"
bLogExist = 0
Else
wscript.echo "Waiting for log"
' do nothing just leave bool to 1
End if
    wscript.sleep 30000 'check every 30 seconds for the log file then once found continue
Wend 




'now check the loop in a loop to check when the MainEngine Thread is finished then return error code
bLogCheck = 1
strMainEngineThreadCode = ""
strErrorCode = 999
While bLogCheck = 1
Set objFile = objFSO.OpenTextFile(strLogLoc, 1, False, -1)
i = 0


Do Until objFile.AtEndOfStream
Redim Preserve arrLines(i)
arrLines(i) = objFile.readline
i = i + 1
Loop

For l = UBound(arrLines)-200 to UBound(arrLines)
If InStr(arrLines(l), "]: MainEngineThread is returning") Then
'strMainEngineThreadCode = arrLines(l)
wscript.echo arrLines(l)
for a=1 to len(arrLines(l))
strErrorCode = right(left(arrLines(l),a),1)
Next
bLogCheck = 0
End If
Next
ObjFile.Close
If bLogCheck = 1 Then
wscript.echo "Autodesk still installing"
Else
wscript.echo "Autodesk install completed with error code: " & strErrorCode
End If
If bLogCheck = 1 Then 
wscript.sleep 30000 ' sleep for 30 seconds then check the log again
End If
Wend



wscript.quit strErrorCode

Tuesday 22 May 2012

SCCM - MP_GetAuth error 0x80040E4D after rebuilding secondary site

You may come across this error when rebuilding the secondary site servers in your hierarchy, when checking the MP_GetAuth log. If utilizing the computer account for db access to the site when the server is rebuilt it gets a new SID created in Active Directory. The MSSQL login when linking the login account utilizes this AD SID for authentication.

USE SMS_001 
DROP USER [DOM\DOMSCMSS001$] 
GO 
 
DROP LOGIN [DOM\DOMSCMSS001$] 
 
CREATE LOGIN [DOM\DOMSCMSS001$] 
FROM WINDOWS 
WITH 
DEFAULT_LANGUAGE=[English]; 
 
USE SMS_001 
CREATE USER [DOM\DOMSCMSS001$] FOR LOGIN [DOM\DOMSCMSS001$]; 
GO 
sp_addrolemember 'smsdbrole_MP',[DOM\DOMSCMSS001$] 
GO 
You can see that if checking the SID on the db vs the SID in AD(via adsiedit.msc) that the SID's will more than likely NOT match. If you are to run the above sql query changing as required it will first check the MSSQL cache for TokenAndPermUserStore. This is why the SID's are mismatched as the query found the SID in the cache NOT AD. In order to resolve the issue of the mismatched SID you are required to clear the TokenAndPermUserStore using DBCC.. You can check the current cache size by running the following sql query:

select name, count(*) from sys.dm_os_memory_cache_entries
      where name = 'TokenAndPermUserStore'
      group by name
      order by count(*) desc ;
GO

To clear the cache run the following sql query on the db:

DBCC FREESYSTEMCACHE ('TokenAndPermUserStore');

Then recreate the account on the db, everything should now be working fine

Monday 21 May 2012

SCCM - ClientAgent - Check installed correct

This is a quick script I wrote to ensure the agent was installing correctly on secondary servers. However should work anywhere, some slight modifications may be required. Also can be used in conjunction with a number of other scripts and checks.



CheckAgent()


Sub CheckAgent()
On Error Resume Next

strCmd = objShell.ExpandEnvironmentStrings("%comspec%")
objShell = WScript.CreateObject("WScript.Shell")
wscript.echo "Checking the state of the SMSAgent"
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Err.Clear
theService = "CcmExec"
bInstallClient = False
bReinstallClient = False
bServiceExists = False
Set colServiceList = objWMIService.ExecQuery("Select * from Win32_Service where Name = '" & theService & "'")
If (Err.Number = 0) And IsObject(colServiceList) Then
If colServiceList.Count > 0 Then
bServiceExists = True
'wscript.echo "SMSAgent Service Exists"
Else
bServiceExists = False
wscript.echo "ERROR service does not exist: " & theService
End If
If bServiceExists = True Then
Set oSMSClient = CreateObject("Microsoft.SMS.Client")
If Err.Number <> 0 Then
'Client is not installed correctly
bReinstallClient = True
Else
'wscript.echo "SMSAgent health seems to be fine"
bReinstallClient = False
End If
Else
bInstallClient = True
End If
If bReinstallClient = False And bServiceExists = True Then
site = UCase(oSMSClient.GetAssignedSite)
If Len(site) < 1 Then
'not assigned to a valid site
wscript.echo "SMSAgent not assigned to a valid site"
wscript.msgbox("Please check the SMSAgent the site is not assigned")
Else
'wscript.echo "SMSAgent seems to be working fine"
End If
End If
End If
If bInstallClient = True Then
wscript.echo "INSTALLING THE SMSAGENT PLEASE WAIT"
cMD = strCmd & " /c C:\windows\system32\ccmsetup\ccmsetup.exe"
Return = objShell.Run(cMD,1,True)
End If
If bReinstallClient = True Then
If FileMinsSinceModified("c:\windows\system32\ccmsetup\ccmsetup.log") < 15 Then
strMsg = "It seems ccmsetup was run in only" & vbCrLf & _
FileMinsSinceModified("c:\windows\system32\ccmsetup\ccmsetup.log") & " minutes ago.." & vbCrLf & _
"are you sure you wish to continue the CCMEXEC reinstall?" & vbCrLf & _
"this install may take some time if you continue"
return=wscript.msgbox(strMsg,4,"CONTINUE REINSTALL?")
If return = 6 Then
wscript.echo "UNINSTALLING THE SMSAGENT PLEASE WAIT"
cMD = strCmd & " /c C:\windows\system32\ccmsetup\ccmsetup.exe /uninstall"
Return = objShell.Run(cMD,1,True)
wscript.echo "INSTALLING THE SMSAGENT. DO NOT CLOSE THE CMD WINDOW!"
cMD = strCmd & " /c C:\windows\system32\ccmsetup\ccmsetup.exe"
Return = objShell.Run(cMD,1,True)
Else
wscript.echo "Reinstallation will not continue at this time.."
End If
Else
wscript.echo "UNINSTALLING THE SMSAGENT PLEASE WAIT"
cMD = strCmd & " /c C:\windows\system32\ccmsetup\ccmsetup.exe /uninstall"
Return = objShell.Run(cMD,1,True)
wscript.echo "INSTALLING THE SMSAGENT. DO NOT CLOSE THE CMD WINDOW!"
cMD = strCmd & " /c C:\windows\system32\ccmsetup\ccmsetup.exe"
Return = objShell.Run(cMD,1,True)
End If
End If
If bServiceExists = True And bReinstallClient = False and bInstallClient = False Then
wscript.echo "SMSAgent seems to be fine"
Else
wscript.echo "The SMSAgent had an issue, Check to see if it was installed or reinstalled"
End If
Set colServiceList = Nothing
Set oSMSClient = Nothing
On Error GoTo 0
End Sub


Function FileMinsSinceModified(filename)
On Error Resume Next
Dim daysold, fso, f, filespec_date
set fso = CreateObject("Scripting.FileSystemObject")
FileMinsSinceModified = 0
If fso.FileExists(UCase(filename)) Then
Set f = fso.GetFile(filename)
filespec_date = f.DateLastModified
Set f = Nothing
If IsDate(filespec_date) Then
minsold = DateDiff("n", filespec_date,Now())
FileMinsSinceModified = minsold 
Else
wscript.echo "WARNING: Not a valid date: " & filespec_date 
End If
Else
wscript.echo "The file does not exist: " & filename 
End If
End Function