In my previous Blog, I discussed how to use PowerShell script to delete files old than certain days. At the time I was focused on the files (log files in particular). Recently there is a need to do the similar thing for folders like if you have Backup folder contain sub backup folders created on different date. Here is a modified script to get the job done.
Function RemoveOldFile
{
param ($strComputer = $(Read-Host "Please Enter The Server Name")),
($Dir = $(Read-host "Please Enter The Directory Path"))
($Days = $(Read-Host "How Many Days?"))
$TargetFolder = "\\" + $strComputer + "\" + $Dir
if (Test-Path $TargetFolder)
{
#Warn you the targeted folder, so you can double check
Write-host "The Targeted Folder is:" $TargetFolder -foregroundcolor "Red"
Write-Host `a `a `a `a `a
Write-Host "If This Is Not The Intended Target, Press 'Ctrl + C' To Exit" -foregroundcolor "Yellow"
Start-sleep -s 15
$Now = Get-Date
# Notice the minus sign before $days
$LastWrite = $Now.AddDays(-$days)
Get-ChildItem $Targetfolder |Where {$_.LastWriteTime -le "$LastWrite"}|remove-item -recurse
}
Else
{Write-Host "The Folder $TargetFolder Does Not Exist!"}
}
RemoveOldFile
Enjoy!
We have a VMWare infrastructure which connects to the SAN. Every now and then we will get "running out disk space" error for a particular LUN. What we need to do is to identify what other machines are on the same LUN, then we can address the disk space issue accordingly. Here is a PowerShell one liner to accomplish this and of course you need to have VMWare VI ToolKit installed.
Get-ESX # to connect to the target ESX box
Get-vm -datastore "lunxy"
If you keep getting request to create multiple (service) accounts in AD, you got to think what PowerShell can do for this task. Before Microsoft releases it's own AD Cmdlets, we will have to use PowerShell commands for Active Directory from quest. You can download the latest version Here.
After you get it installed, you can start a regular PowerShell session and type:
Add-PSSnapIn Quest.ActiveRoles.ADManagement
This will extend the PowerShell for AD
First we save the plaintext password as a AsSecureString
PS C:\Users\yl.admin\Documents\PS> $pw = read-host "Enter password" -AsSecureString
Enter password: ********
Then connect to the targeted domain
PS C:\Users\yl.admin\Documents\PS> Connect-QADService -service 'xyzdcs01.xyz-stage.com' -ConnectionAccount 'xyz-stage\administrator' -ConnectionPassword $pw
Once you establish the connection to AD, you can import the csv file which has the below format:
Name Description
Svc_SP_IntrAP Intranet content web application pool
Svc_SP_IntrSSPAP Intranet farm shared services provider application pool
PS C:\Users\yl.admin\Documents\PS> import-csv C:\myworkspace\user.csv |%{new-qadUser -ParentContainer 'OU=Service Ac
ts,DC=xyz-stage,DC=com' -name $_.name -samAccountName $_.name -description $_.Description}
You will see the list of accounts created after you run the above script.
After we got a list of computers need BITS 2.5 discussed in my previous Post. We could use the below script to push BITS 2.5 to them
$colComputers = gc c:\users\yl.admin\pstools\ComputerList.txt
Foreach ($strComputer in $colComputers)
{.\psexec.exe -c \\$strComputer \\server\share\WindowsXP-KB923845-x86-ENU.exe /quiet /norestart}
You will see something like this which is perfectly fine and it just means reboot is required and pending!
WindowsXP-KB923845-x86-ENU.exe exited on $strcomputer with error code 3010.
BITS 2.5 is a required component by ConfigMgr 2007. The ccmsetup will automatically install BITS 2.5 if the client doesn't have it but there is a little catch - it will reboot the machine! I have been trying to find a way to suppress the reboot and so far without success.
It seem the only way to control the reboot is to pre-install BITS 2.5. Before I do that, here is a PowerShell script to query BITS version on multiple remote computers.
$erroractionpreference = "SilentlyContinue"
$a = New-Object -comobject Excel.Application
$a.visible = $True
$b = $a.Workbooks.Add()
$c = $b.Worksheets.Item(1)
$c.Cells.Item(1,1) = "Machine Name"
$c.Cells.Item(1,2) = "Ping Status"
$c.Cells.Item(1,3) = "File Name"
$c.Cells.Item(1,4) = "Version"
$c.Cells.Item(1,5) = "Report Time Stamp"
$d = $c.UsedRange
$d.Interior.ColorIndex = 19
$d.Font.ColorIndex = 11
$d.Font.Bold = $True
$intRow = 2
$colComputers = gc c:\myworkspace\MachineList.txt
foreach ($strComputer in $colComputers)
{
$c.Cells.Item($intRow,1) = $strComputer.ToUpper()
Function PingComputer
{
$ping = new-object System.Net.NetworkInformation.Ping
$Reply = $ping.send($strComputer)
if($Reply.status –eq “Success”)
{
$c.Cells.Item($intRow, 2) = “Online”
Function GetFileInfo
{
$OSVersion = (gwmi -class Win32_OperatingSystem -computer $strComputer).version
if ($OSVersion -le 5.1)
{
$Path = "\\"+ $strComputer + "\C$\Winnt\System32\qmgr.dll"
}
else
{
$Path = "\\"+ $strComputer + "\C$\Windows\System32\qmgr.dll"
}
$File = get-item $Path
$c.Cells.Item($intRow,3) = $File.Name
$c.Cells.Item($intRow,4) = $File.VersionInfo.Productversion
}
GetFileInfo
}
else
{
$c.Cells.Item($intRow, 2).Interior.ColorIndex = 3
$c.Cells.Item($intRow, 2) = "Offline"
}
}
PingComputer
$c.Cells.Item($intRow,5) = Get-date
$ping.status = $null
$intRow = $intRow + 1
}
$d.EntireColumn.AutoFit()
In my previous post, I described how to get your ConfigMgr SP1 environment up and running in no time. Now here is a update version for how to set up ConfigMgr SP1 environment in Windows Server 2008. Enjoy!
We have a development domain setup inside (VMWare) Labmanager which is "isolated" from outside. Each machine has it's private IP address such as 10.10.10.x and also has an "external" IP Address such as 172.16.48.x. There is a need to add machine external to labmanager which has 172.16.48.* address to this dev domain.
When I try to join a test XP machine to the domain I receive the following message:
Note: This information is intended for a network administrator. If you are not your network's administrator, notify the administrator that you received this information, which has been recorded in the file C:\WINDOWS\debug\dcdiag.txt.
The following error occurred when DNS was queried for the service location (SRV) resource record used to locate a domain controller for domain xyz-dev.com:
The error was: "This operation returned because the timeout period expired."
(error code 0x000005B4 ERROR_TIMEOUT)
The query was for the SRV record for _ldap._tcp.dc._msdcs.xyz-dev.com
The DNS servers used by this computer for name resolution are not responding. This computer is configured to use DNS servers with the following IP addresses:
172.16.48.10
Verify that this computer is connected to the network, that these are the correct DNS server IP addresses, and that at least one of the DNS servers is running.
For more information on how to correct this problem, click Help.
172.16.48.10 is the "external" IP address for the domain controller/DNS server in dev domain
In order to correct this error, I added the following to the host file on the XP test machine
172.16.48.10 xyz-dev.com
The I see some progress and got a different error:
DNS was successfully queried for the service location (SRV) resource record used to locate a domain controller for domain xyz-dev.com:
The query was for the SRV record for _ldap._tcp.dc._msdcs.xyz-dev.com
The following domain controllers were identified by the query:
xyzdcd01.xyz-dev.com
Common causes of this error include:
- Host (A) records that map the name of the domain controller to its IP addresses are missing or contain incorrect addresses.
- Domain controllers registered in DNS are not connected to the network or are not running.
For information about correcting this problem, click Help.
Even after I added the below entry in the host file - I still get the same error messag:
172.16.48.10 xyzdcd01.xyz-dev.com
After give it some thought. I believe the problem is because the test machine can resolve to xyz-dev.com through the first entry in the host file
172.16.48.10 xyz-dev.com
it queries the SRV record and got the domain controller name which is xyzdcd01.xyz-dev.com - all happy so far!
but the IP address the test machine got for the DC is not 172.16.48.10 but rather the internal IP address of the DC/DNS box which happens to be 10.10.10.10 which the test box has no way to connect to and the second entry in host file
172.16.48.10 xyzdcd01.xyz-dev.com doesn't help at all!
I tried to create a new Host(A) record for the DC let the xyzdcd01.xyz-dev.com has two A record one is point to internal IP address 10.10.10.10 and the other point to external IP address 172.16.48.10 and I can then add the test xp machine to the domain. But before I got too excited about this - I realizes and noticed that I can't do that, the DNS server automatically delete the "external" A record for the DC after a while!
Then I went back to read the above error message and focus my attention on:
_ldap._tcp.dc._msdcs.xyz-dev.com
I then go to the DNS server and modify the above pointer to the external IP address 172.16.48.10 (it had the internal IP address by default)!
Now the "external" machines can join the dev domain and the machine inside the labmanagers can still join the dev domain because they each has an external IP address and they can go out (they are setup to use the external getaway) to join the domain.
After that I created a secondary DNS zone on my "external" production DNS server which now hold the zone information for xyz-dev, so I don't have to add the xyz-dev.com host file entry. All I need to do is to let the client using the external IP address of the dev DNS server as it's preferred DNS server IP address if I need to add that client to the dev domain.
I spent quite some time on this and figure to share them but keep in mind, this may not be an officially supported scenario and may have unintended consequences!
Forget about the trip to Las Vegas I mentioned before, I started to like VMWare VI Tookkit the more I use it!
You just need to cultivate a habit, every time if you need to repetitively doing something, you should ask yourself if you can do it with PowerShll. More likely than not, the answer is YES, WE CAN!
Like I have a bunch of cloned vm box acting as a backup to our MOSS staging environment. We are tight on resource and so we decided to delete all the clones. Instead right click one by one, you can use the below script. Thanks Hal's comment to my previous post, it's now much simpler!
get-vm clone*|remove-vm -deletedfromdisk
But I do notice that after I remove vm this way, I got something like
clone-xyz(orphaned), you may have to add remove-inventory but I wasn't able to test this part!
Similarly you could do:
get-vm xyzmoss* |shutdown-vmguest
and
get-vm xyzmoss* |start-vm
In my previous Blog, I introduced some basics about VMWare Infrastructure Toolkit. Now let's put it into action!
Let's say you have a test MOSS or SMS virtual environment, you have a couple of servers and you configured everything and test everything. Before you make the next big change, you may want to take a snapshot of your machines so you can have some to fall back on if something goes bad!
It couldn't easier with VI Toolkit!
$Now = Get-Date
#get all your moss servers
$VMs = get-vm |where{$_.name -like "xyzmoss*"}
foreach ($vm in $VMs)
#Take snapshots for each VM Box
{new-snapshot -vm $vm -name $Now -confirm}
Here is a KB article explains how to refresh the Group Policy Settings on remote computers. Basiclly you need to download PsTools from SysInternals and run something like this:
For Windows XP Computers:
Psexec.exe -@ComputerList.txt Gpupdate.exe /Target:User /force
Psexec.exe -@ComputerList.txt Gpupdate.exe /Target:Computer /force
Where you have the computer names in the ComputerList.txt file. I made a little effort to translate that into PowerShell
$colComputers = gc c:\users\yl.admin\pstools\ComputerList.txt
Foreach ($strComputer in $colComputers)
{.\psexec.exe \\$strComputer gpupdate.exe /target:computer /force}
You can change the target to user at you wish.
Right after I imported a couple of new MP to our OpsMgr environment, I started to get the below alert:
Alert: Data Warehouse failed to enumerate database components to be deployed
Source: XYZOPMP01.related.com
Path: XYZOPMP01.related.com
Last modified by: System
Last modified time: 8/12/2008 7:24:26 PM Alert description: Data Warehouse failed to enumerate database components to be deployed. Failed to enumerate Data Warehouse components for deployment. The operation will be retried.
Exception 'SqlException': Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
One or more workflows were affected by this.
Workflow name: Microsoft.SystemCenter.DataWarehouse.Deployment.Component
Instance name: XYZOPMP01.related.com
Instance ID: {986ED2F5-5B26-0554-2092-0FF3851DFA86}
Management group: XYZ Enterprise Apps
We have OpsMgr SP1 and the latest Data Warehouse Library (6.0.6278.0). The fix from Vitaly Filimonov [MSFT] is to run sp_updatestats on OperationsManagerDW DB and it indeed solved our problem!
Recently VMWare released their version of PowerShell Cmdlets called VI ToolKit. You can download it Here and it is free!
VMWare is also challenging the world's VI administrators for a scripting contest, you can win a trip to VMworld 2008 Las Vegas or $5000 cash. Sounds too good to be true - it is not!
But before we get too excited, we have to setup a good foundation - At least we need to get it installed before we can write anything!
The installation itself is very straight forward process but it requires PowerShell v1.0 and it won't work with PowerShell CTP 2.0.
Some cmdlets only supported in API version 2.5 or newer.
After the setup you can start the Toolkit from start - all programs - VMware - VMWare VI Toolkit - VMWare VI Toolkit (for Windows) or
If you like me, "hate" to open one powershell console for each application, you can open the regular powershell console and run:
Add-PSSnapin VMWare.VImAutomation.Core and then run Initialize-VIToolkitEnvironment.ps1 in C:\Program Files\VMware\Infrastructure\VIToolkitForWindows\Scripts
Now you regular powershell console becomes VMWare VI Toolkit!
By now we have everything in order, we can put VMWare VI Toolkit in action.
you can go get-VC or Get-ESX to connect to your virtual center or ESX host
after you connect to your VC or ESX, you can do
get-vm |select name, powerstate
You will get something like:
MOSS-SQLS01
PoweredOn
SCCMS01
PoweredOn
MOSS-SPRS01
PoweredOn
VEMS01
PoweredOn
Clone-ANSS01
PoweredOff
Clone-APPS01
PoweredOff
Clone-SPRS01
PoweredOff
SCCMS04
PoweredOn
...
You can do start-vm "clone-anss01" to poweron the vm box
or stop-vm "SCCMS01" to poweredoff the vm box
To get a list of VI command, type:
get-vicommand
I only played with it for a couple of hours and I like it already. It indeed feels and looks like PowerShell! From here, your imagination is your limit - I don't know about you, I started to hear the slot machine singing already. :)
In my previous post, I blogged about how to use PowerShell to retrieve scheduled tasks (Task Scheduler API). Today I will go one step further and discuss how to create a scheduled task using PowerShell. This will run only on Vista/Windows Server 2008!
#First we create the TaskService object and connect to remote Windows Server 2008 box "Whatever"
$ST = new-object -com("Schedule.Service")
$ST.connect("Whatever")
#Get to root folder (\) to create the task definition
$RootFolder = $ST.getfolder("\")
$TaskDef = $ST.NewTask(0) # Still I couldn't explain why we need a 0!
#Now we define the task, creating the $RegiInfo object
$RegInfo = $Taskdef.RegistrationInfo
$Reginfo.Description = "Task will send email when a specified user logs on"
$Reginfo.Author = "Mydoamin\yl.admin"
$Settings = $Taskdef.Settings
$Settings.StartWhenAvailable = $True
#Next we will create a logon trigger
$Triggers = $Taskdef.Triggers
$Trigger = $Triggers.Create(9) # 9 is TASK_TRIGGER_LOGON
#We will define when the trigger will be active in UTC time format and convert to EST (-05:00)
$Starttime = "2008-08-05T12:00:00-05:00"
$Endtime = "2008-08-06T12:00:00-05:00"
$Trigger.StartBoundary = $Starttime
$Trigger.EndBoundary = $Endtime
$Trigger.ExecutionTimeLimit = "PT5M" # time out in 5 minutes
$Trigger.Userid = "mydomain\yli" # must be a valid user
#Next we will create the action for the task to execute which is sending an #email 6 - TASK_ACTION_SEND_EMAIL
$Action = $Taskdef.Actions.Create(6)
$Action.Server = "smtp.contoso.com"
$Action.Body = "This is the email message."
$Action.From = "ying.li@contoso.com"
$Action.Subject = "This is the subject."
$Action.to = ying.li@contoso.com
#Last but not least is we will have to register or create the task
$Rootfolder.RegisterTaskDefinition("Test", $Taskdef, 6, "mydomainyl.admin", "Password", 3)
#Where "test" is the name or path of the Task
#$Taskdef is the task defination
#6 meansTASK_CREATE_OR_UPDATE
#username
#password
#3 means Task_Logon_Interactive_token - the task will be run only in an existing interactive session.
Guess what, we just create a scheduled task using PowerShell! The trigger - someone logon to a remote windows server 2008 box; The action - to send an email.
As you may already noticed, when working with Windows Server 2008, there are a lot of nuances we need to pay attention like if you are trying to open Microsoft SQL Server Management Studio, you will get an error like below even though the account you use has the admin right on SQL
What we need to do is to use Run As Administrator to start SQL Server Management Studio to bypass that error!
As you may already know that Windows PowerShell 1.0 for the first time included as part of the Windows Operating System on Windows Server 2008. But where is it on Windows Server 2008 - for a brand new install Windows Server 2008, you can't find it in Start - All Programs!
This is because Windows Sever 2008 is a role/service, feature based OS and by default it doesn't install or enable much.
Windows PowerShell is a feature need to be enabled on Windows Server 2008 box. See below figure:

I have a couple of brand new Windows Server 2008 setup and trying to push OpsMgr agent to them but I got the below error:
The MOM Server would not execute WMI Query "Select * from Win32_Operatingsystem" on computer xyzsmsp02.whatever.com.
Operation:Agent Install
Install account: my domain admin account
Error Code: 800706BA
Error Description: The RPC server is unavailable
As we already know by default Windows Server 2008 doesn't install much and block "everything"!
All we have to do to fix the above error is to go to Windows Firewall on the Windows server 2008 box and enable WMI exception!
I am setting up ConfigMgr SP1 on Windows Server 2008 and I installed WSUS 3.0 SP1 and the SUSDB resides on the same box with ConfigMgr Database. After the setup, I am trying to follow the SQL best practice to move the Logs to a different drive.
There are plenty posts on the web about how you move a SQL 2005 Database or Log files to a different place or you can search SQL online help:
Here are some of the recommend options:
1) Detach and re attach the Database;
2) Backup the Database and then restore.
But when I tried to detach SUSDB, I get the following error:
"Cannot detach the database 'SUSDB' because it is currently in use"
So who is using SUSDB?
IIS Admin Service
Update Services (Not Windows Update Service!)
You need to stop both service to successfully detach SUSDB!
You know how to do the rest.
Rod Trent posted a PowerShell script for Getting the List of Scheduled Tasks. I have the need the other day to retrieve scheduled tasks on a remote server. I give it a try but to my surprise, it doesn't return anything while I know I have tasks scheduled on that box. Why?
This is because that Windows has two different APIs to manage scheduled tasks
1) The Task Scheduler API used by Task Scheduler and by Schtasks.exe, a command-line task management tool that ships with XP/Windows 2003 and beyond;
2) So called AT APIs used by At.exe and by WMI's Win32_Scheduled class.
So Rod's script covered the AT API and apparently my tasks weren't scheduled that way and hence why I couldn't retrieve anything.
Now the question is can we use script, PowerShell in particular to retrieve the tasks scheduled using Task Scheduler API? Yes, we can! But you will need Windows Vista to accomplish that.
First we need to create an instance of Schedule.Service (COM) object, then we will need to use the connect method to actually connect to the service. By default it will connect to the local machine but you could specify a remote computer to connect to like below, we are connecting to a computer called "Whatever"
$ST = new-object -com("Schedule.Service")
$ST.connect("whatever")
Next we need to retrieve the object reference to the folder we want to search. In my case, that's the root folder(\):
$RootFolder = $ST.getfolder("\")
We then use the GetTasks method to get a collection of all the tasks in the folder targeted.
$ScheduledTasks = $root.GetTasks(0)
The parameter (0) to the GetTasks method is required - Why? I don't know!
Last but not least, We get what what we looking for - The tasks scheduled on the remote machine!
$ScheduledTasks | select name, path, enabled, lastruntime, nextruntime
Name : WhateverUpdater
Path : \WhateverUpdater
Enabled : True
LastRunTime : 7/28/2008 4:30:00 AM
NextRunTime : 7/29/2008 4:30:00 AM
Name : XYZ
Path : \XYZ
Enabled : True
LastRunTime : 7/28/2008 4:00:00 AM
NextRunTime : 7/29/2008 4:00:00 AM
Now with Rod's AT API and my Task Scheduler API, we get Scheduled Tasks covered!
The other day, I was working with Quest support for the eXc Blackberry monitoring software. We tried to delete/import their MP. During the process, I will need to input the password for the account which OpsMgr SDK Service and OpsMgr Config Service are running under. I found the password and I want to verify it. I didn't use the SDK service to verify concerning that if I don't have the correct password, I will not be able to restart the service. So I use OpsMgr Healthservice instead thinking I could easily switch back to local system account. I did exactly that and a few minutes if not seconds later, I noticed that all my agents are grayed out (unknown status!).
At first, we thought this is because we deleted/import the MP -bogs down SQL database. I thought to let it run over the weekend and hoping that it will fix itself. On Monday, all the agents are still grayed out only the agent for the RMS is green. I called PSS support, MS engineer determine this is because "Duplicate SPN". He did Setspn -l which didn't catch it or didn't catch all the duplicates. He then use MS internal VBscript to identify more duplicates. The moment after we clean up the "Duplicate SPN", we restarted the RMS and the agents are starting coming back green!
I mentioned that the OpsMgr Healthservice account "swap" to MS engineer but he didn't link this two events together. I did some digging and found out that's exact the cause why all my agents turn gray. The Healthservice account (especially on RMS) must run under local system account or you will get duplicate SPN. Even after you switch the account back. Before I thought running under local system account is preferred but not knowing it is a "MUST"! I never realized that simply by change the OpsMgr Healthservice account on RMS can cause so much trouble and it costed me a support ticket. :)
Next time if all your agents are grayed out - Check your SPN first!
Every now and then, I get an alert like this:
Alert: Agent proxying needs to be enabled for a health service to submit discovery data about other computers.
Source: xyzopmp04.related.com
Path: xyzopmp04.related.com
Last modified by: System
Last modified time: 7/21/2008 8:18:46 PM Alert description: Details:Health service ( 9AAFF032-4567-2270-B09A-A34025D969F3 ) should not generate data about this managed object ( EC7903B7-72FC-BFD0-3CA2-473774E60AD4 ).
Alert view link: "http://XYZOPMP01:51908/default.aspx?DisplayMode=Pivot&AlertID={0b2c1100-f167-4691-b271-e209632392bf}"
Notification subscription ID generating this message: {4B6F3971-955E-1491-6D82-5C22F1466FC2
This is common and all we need to do is to identify the agent and then enable proxy.
How we translate something like this - 'EC7903B7-72FC-BFD0-3CA2-473774E60AD4' to the computer name?
1, We can run a SQL query in OperationManagerDB
select * from basemanagedentity where basemanagedentityid =
'EC7903B7-72FC-BFD0-3CA2-473774E60AD4'
2, We could use PowerShell
Save the below script as whatever.ps1
Param([string]$MonitoringObjectID)
Get-MonitoringObject -id $MonitoringObjectID | select name
Then run it from command shell console:
c:\MyWorkSpace\whatever.ps1 EC7903B7-72FC-BFD0-3CA2-473774E60AD4
Either way, you will get the computer name and then you can go to your OpsMgr console to enable proxying for the agent!
The DNS WMI provider exposes a number of DNS objects, including DNS Servers, DNS domains, DNS Zones and DNS Resource Records etc. We could use these objects to manage DNS and you guess it, through PowerShell!
The DNS WMI Provider is installed on Windows Server 2003 by default. For Windows 2000, you could obtain the DNS WMI Provider from Windows 2000 Server Resource Kit or follow this Link
Here is a PowerShell script to list DNS Zones
Get-WmiObject -namespace "root\MicrosoftDNS" -class MicrosoftDNS_Zone -Credential DnsServer\Administrator -ComputerName DnsServer
This will list all the DNS zones on your DNS server(Microsoft DNS server, that is)!
If you want to see what other classes are there
Get-WmiObject -namespace "root\MicrosoftDNS" -Credential DnsServer\Admin
istrator -ComputerName DnsServer -list
__SystemClass __NAMESPACE
__Provider __Win32Provider
__ProviderRegistration __ObjectProviderRegistration
__ClassProviderRegistration __InstanceProviderRegistration
__PropertyProviderRegistration __MethodProviderRegistration
__EventProviderRegistration __EventConsumerProviderRegistration
__NotifyStatus __ExtendedStatus
__CIMOMIdentification __SecurityRelatedClass
__NTLMUser9X __IndicationRelated
__Event __PARAMETERS
__ExtrinsicEvent __NamespaceOperationEvent
__NamespaceCreationEvent __NamespaceDeletionEvent
__NamespaceModificationEvent __ClassOperationEvent
__ClassCreationEvent __ClassDeletionEvent
__ClassModificationEvent __InstanceOperationEvent
__InstanceCreationEvent __InstanceDeletionEvent
__InstanceModificationEvent __TimerEvent
__AggregateEvent __EventConsumer
__EventFilter __FilterToConsumerBinding
__EventGenerator __TimerInstruction
__AbsoluteTimerInstruction __IntervalTimerInstruction
__TimerNextFiring __SystemEvent
__EventDroppedEvent __EventQueueOverflowEvent
__ConsumerFailureEvent __SystemSecurity
CIM_ManagedSystemElement CIM_LogicalElement
CIM_Service MicrosoftDNS_Server
MicrosoftDNS_Domain MicrosoftDNS_Zone
MicrosoftDNS_Cache MicrosoftDNS_RootHints
MicrosoftDNS_ResourceRecord MicrosoftDNS_AType
MicrosoftDNS_SOAType MicrosoftDNS_PTRType
MicrosoftDNS_NSType MicrosoftDNS_CNAMEType
MicrosoftDNS_MBType MicrosoftDNS_MDType
MicrosoftDNS_MFType MicrosoftDNS_MGType
MicrosoftDNS_MRType MicrosoftDNS_MINFOType
MicrosoftDNS_RPType MicrosoftDNS_MXType
MicrosoftDNS_AFSDBType MicrosoftDNS_RTType
MicrosoftDNS_HINFOType MicrosoftDNS_ISDNType
MicrosoftDNS_TXTType MicrosoftDNS_X25Type
MicrosoftDNS_WKSType MicrosoftDNS_AAAAType
MicrosoftDNS_SRVType MicrosoftDNS_ATMAType
MicrosoftDNS_WINSType MicrosoftDNS_WINSRType
CIM_Component MicrosoftDNS_ServerDomainContainment
MicrosoftDNS_DomainDomainContainment MicrosoftDNS_DomainResourceRecordContainment
from here, you could replace MicrosoftDNS_Zone class with MicrosoftDNS_ResourceRecord class etc.
Have fun!
This is an update version of my previous Post
I realize there are may be confusions regarding running OpsMgr related script in regular PowerShell console for some people. This script is for you to directly running from the command shell which comes with OpsMgr console;
I used computerPrincipalName in my previous post, which is FQDN, to save some typing, I use computername instead;
last but not least, I modified the script to work with multiple computers. Enjoy!
*********************************************************************
param($computerNames,$numberOfHoursInMaintenanceMode,$comment)
Foreach ($computerName in $ComputerNames)
{
$computer = Get-Agent | Where-object {$_.ComputerName –eq $computerName}
$healthService = $computer.HostedHealthService
$healthServiceWatcherClass = get-monitoringclass -name:Microsoft.SystemCenter.HealthServiceWatcher
$healthServiceCriteria = "HealthServiceName='" + $computer.PrincipalName + "'"
$healthServiceWatcher = get-monitoringobject -monitoringclass:$healthServiceWatcherClass -criteria:$healthServiceCriteria
$startTime = [System.DateTime]::Now
$endTime = $startTime.AddHours($numberOfHoursInMaintenanceMode)
"Putting " + $computerName + " into maintenance mode"
New-MaintenanceWindow -startTime:$startTime -endTime:$endTime -monitoringObject:$computer.HostComputer -comment:$comment
"Putting the associated health service into maintenance mode"
New-MaintenanceWindow -startTime:$startTime -endTime:$endTime -monitoringObject:$healthService -comment:$comment
"Putting the associated health service watcher into maintenance mode"
New-MaintenanceWindow -startTime:$startTime -endTime:$endTime -monitoringObject:$healthServiceWatcher -comment:$comment
#To confirm your result and the returned time is Universal Time
Get-MaintenanceWindow -MonitoringObject $computer.hostcomputer
}
*************************************************************************
Save the above script (Between the lines) as whatever.ps1
Start your command shell with your admin (for OpsMgr) account and type the following in the prompt
PS Monitoring:\XYZPMP01
>c:\MyWorkSpace\Whatever.ps1 (gc c:\MyWorkSpace\list.txt) 0.25 'UpdateXXX'
Your list.txt should look like this:
server1
server2
...
Here is a PowerShell script to check OpsMgr Agents Service and HealthState
You need to either run it in Operation Manager's own command shell or you can use regular PowerShell console as mentioned in my previous post Here
Below is what's in AddConnSCOMSnapin.ps1
Add-PSSnapin "Microsoft.EnterpriseManagement.OperationsManager.Client"
Set-Location "OperationsManagerMonitoring::"
$rootMS = "XYZOPMP01"
new-managementGroupConnection -ConnectionString:$rootMS
Set-Location $rootMS
PS C:\Documents and Settings\yl.admin\My Documents\PS> .\AddConnSCOMSnapin.ps1
PathName :
ManagementGroup : XYZ Enterprise Apps
ManagementServerName : XYZOPMP01
Drives :
PS Microsoft.EnterpriseManagement.OperationsManager.Client\OperationsManagerMonitoring::XYZOPMP01> & "C:\Documents and Settings\yl.admin\My Documents\PS\CheckAgentHealth.ps1"
Below is the script - CheckAgentHealth.ps1
#Start
$erroractionpreference = "SilentlyContinue"
$a = New-Object -comobject Excel.Application
$a.visible = $True
$b = $a.Workbooks.Add()
$c = $b.Worksheets.Item(1)
$c.Cells.Item(1,1) = "Machine Name"
$c.Cells.Item(1,2) = "Ping Status"
$c.Cells.Item(1,3) = "Health Service Status"
$c.Cells.Item(1,4) = "Health State"
$d = $c.UsedRange
$d.Interior.ColorIndex = 19
$d.Font.ColorIndex = 11
$d.Font.Bold = $True
$d.EntireColumn.AutoFit($True)
$intRow = 2
#get all the agent managed servers from OpsMgr
$ColServers = get-agent
foreach ($strServer in $colServers)
{
$c.Cells.Item($intRow, 1) = $strServer.Computername.ToUpper()
# Ping each server
Function PingServer
{
$ping = new-object System.Net.NetworkInformation.Ping
$Reply = $ping.send($strServer.Computername)
if ($Reply.status –eq “Success”)
{
$c.Cells.Item($intRow, 2) = “Online”
}
else
{
$c.Cells.Item($intRow, 2).Interior.ColorIndex = 3
$c.Cells.Item($intRow, 2) = "Offline"
}
}
PingServer
#Check if the HealthService is running
Function CheckHealthService
{
$HealthService = [System.ServiceProcess.ServiceController]::GetServices($strServer.Computername) | where{$_.name -eq 'HealthService'}
If ($HealthService.status -eq "Running")
{
$c.Cells.Item($intRow, 3) = "Running"
}
ElseIf($HealthService.Status -eq "Stopped")
{
$c.Cells.Item($intRow, 3).Interior.ColorIndex = 3
$c.Cells.Item($intRow, 3) = "Stopped"
#You can start the service here if you want to
#$HealthService.Start()
}
Else
{
$c.Cells.Item($intRow, 3).Interior.ColorIndex = 6
$c.Cells.Item($intRow, 3) = "Not Sure"
}
}
CheckHealthService
# get the HealthState of the agents
#(you will get a number: 0-uninitialized; 1-success; 2-warning; 3-errors)
$c.Cells.Item($intRow, 4) = $strServer.HealthState
$intRow = $intRow + 1
}
$d.EntireColumn.AutoFit()
#End
When I try to access my OpsMgr 2007 SP1 Web Console remotely as an regular user, I got the below error
The Application Event log on my RMS/Web Console has the below error:
Event Type: Warning
Event Source: ASP.NET 2.0.50727.0
Event Category: Web Event
Event ID: 1309
Date: 7/9/2008
Time: 6:25:38 PM
User: N/A
Computer: XYZOPMP01
Description:
Event code: 3005
Event message: An unhandled exception has occurred.
Event time: 7/9/2008 6:25:38 PM
Event time (UTC): 7/9/2008 10:25:38 PM
Event ID: 8d511823028c45dcbf063fc4d3740b31
Event sequence: 882
Event occurrence: 57
Event detail code: 0
Application information:
Application domain: /LM/W3SVC/2/ROOT-1-128601124183270585
Trust level: Full
Application Virtual Path: /
Application Path: D:\Web Console\
Machine name: XYZPMP01
Process information:
Process ID: 55828
Process name: w3wp.exe
Account name: NT AUTHORITY\NETWORK SERVICE
Exception information:
Exception type: UnauthorizedAccessMonitoringException
Exception message: The user Domain\YLi does not have sufficient permission to perform the operation.
Request information:
Request URL: http://xyzopmp01:51908/InternalPages/NavigationTree.aspx?SpaceId=1001&ViewId=
Request path: /InternalPages/NavigationTree.aspx
User host address: xxx.xxx.xxx.xxx
User: Domain\YLi
Is authenticated: True
Authentication Type: Negotiate
Thread account name: NT AUTHORITY\NETWORK SERVICE
Thread information:
Thread ID: 10
Thread account name: NT AUTHORITY\NETWORK SERVICE
Is impersonating: False
Stack trace: at Microsoft.EnterpriseManagement.DataAbstractionLayer.SdkDataAbstractionLayer.HandleIndigoExceptions(Exception ex)
at Microsoft.EnterpriseManagement.DataAbstractionLayer.TypeSpaceOperations.GetFoldersByCriteria(MonitoringFolderCriteria criteria, String languageCodes)
at Microsoft.EnterpriseManagement.ManagementGroup.GetMonitoringFoldersInternal(MonitoringFolderCriteria criteria)
at Microsoft.EnterpriseManagement.ManagementGroup.GetMonitoringFolders()
at Microsoft.EnterpriseManagement.OperationsManager.DataAbstractionLayer.DataAbstraction.BuildTree(String rootName)
at NavTreeHelper.BuildOperationsTree(IDataAbstraction OpsSdkWrapper)
at NavTreeHelper.BuildSpaceTree(IDataAbstraction OpsSdkWrapper, WunderbarSpace selectedSpace)
at NavigationTree.Page_Load(Object sender, EventArgs e)
at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
at System.EventHandler.Invoke(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Custom event details:
But I know my Web Console works and I can access it on RMS server and I also can access the Web Console remotely using my admin account. So this is definitely a permission issue. I tried to follow some of the post - added my regular user account to Performance Monitor Users group on RMS - no luck!
Finally I added my regular user account to Read-Only Operator group in OpsMgr - Those errors are gone and I can access web console remotely with my regular account!
You would think this is a no brainier but it indeed gets me stuck and also I see some other people has the similar issue Here
So if you run into the above issue, make sure the user account has at least Read-Only Operator role!
Microsoft released PowerShell Provider CTP2 for IIS7 yesterday and you can download it Here
I just installed it on my Vista SP1 machine. It installs without issue (Require you turn on IIS7 and Windows Process Activation Service of course)
I played with it a few and here is how you find your way around
PS IIS:\> dir
Name
----
Sites
AppPools
SslBindings (this is new to CTP2)
PS IIS:\> cd sites
PS IIS:\Sites> dir
Name ID State Physical Path Bindings
---- -- ----- ------------- --------
Default Web Site 1 %SystemDrive%\inetpub\wwwroot
PS IIS:\Sites> cd ..
PS IIS:\> cd apppools
PS IIS:\AppPools> dir
Name State Applications
---- ----- ------------
DefaultAppPool Started Default Web Site
PS IIS:\> get-command
Type: AppPools
CommandType Name Definition
----------- ---- ----------
Cmdlet Add-Content Add-Content [-Path] <String[...
Cmdlet Add-History Add-History [[-InputObject] ...
Cmdlet Add-Member Add-Member [-MemberType] <PS...
Cmdlet Add-Module Add-Module [-Name] <String[]...
Cmdlet Add-PSSnapin Add-PSSnapin [-Name] <String...
Cmdlet Add-Type Add-Type [-TypeDefinition] <...
Cmdlet Add-WebConfiguration Add-WebConfiguration [-Filte...
Cmdlet Add-WebConfigurationProperty Add-WebConfigurationProperty...
Cmdlet Backup-WebConfiguration Backup-WebConfiguration [-Na
…
I wish I will have a production IIS7 environment soon so I could explore this further. I have a feeling it’s going to be very cool!
Quest is holding their Summer Olympics (PowerShell) not in Beijing but Here. You could get your hands dirty with PowerGUI and could potentially win anywhere from $250 to $500 gift certificates to Amazon .com!
Just got an email from Microsoft and I got the 2008 MVP Award in Admin Frameworks. This is the second year in a row! What a great independence day gift! Cheers!
As I promised, I will share this end to end ConfigMgr SP1 setup guide. This is for fresh install not for upgrade. You could literally get your ConfigMgr environment up and running within hours! This is for the core infrastructure and you could extend the hierarchy according to your environment.
Download Doc
Recently I am focused on to design and implement ConfigMgr for our company. Unfortunately there are no native support for PowerShell in ConfigMgr yet. So if you see I am “slacking”, you know why!
But I am finishing up a ConfigMgr SP1 setup guide and will share it soon.
Lately our team received a lot requests to add new DNS records for our testing web server, I am getting tired to add A record in DNS manually for those Host headers in IIS. Here is what I come up
#xyz is dns servername
$A = [wmiclass]"\\xyz\root\MicrosoftDNS:MicrosoftDNS_AType"
$DNSServer = "xyz.R-test.com"
$Zone = "R-Test.com"
$class = 1
$TTL = 3600
#This is your web server IP Address
$IPAddress = "192.168.1.88"
$Sites = Get-content WebSites.txt
Foreach ($Site in $Sites)
{
$A.CreateInstanceFromPropertyData($DNSserver, $zone, $Site, $class, $ttl, $IPAddress)
}
The WebSites.txt is something look like this:
whatever1.R-test.comwhatever2.R-test.comwhatever3.R-test.com
whatever4.R-test.com
…
If whateverx already has a DNS A record, you will get something like this:
Exception calling "CreateInstanceFromPropertyData" : "Generic failure "
At C:\Documents and Settings\Administrator.RELATED-TEST\My Documents\AddDNSARecords.ps1:13 cha
+ $A.CreateInstanceFromPropertyData( <<<< $DNSserver, $zone,$Site, $class, $ttl, $IPAddress)
Thanks Richard Siddaway for his post Here
The word is out, at the TechEd 2008 for IT Professional (June 10–13, 2008),
PowerGUI has received the highest award – The breakthrough product of the show. If you haven’t tried already, You can download from the link above. Trust me, you sure will like it! Kudos to Dimitry and his team!
More Posts
Next page »