I have learned this neat trick at a customer site this week. With SCOM 2012 came the possibility of creating management pack bundles, which are capable of carrying the typical MP content, but also files, scripts,etc. The customer uses it to distribute and automate SCOM agent updates (due to some network restrictions, pushing and updating from the console is limited) and the builds also include the agent, so they are by default manual installations (they could be reverted, but…).
But we can imagine other situations, where you need to distribute a file or package, copy it to a certain location, run it, etc. A special Hosts file (yes, there are some apps that still need that kind of thing).
Well, to simplify the example, I will include the steps to create an MP, embed a simple text file, create a script that copies the file to another location in the target server every 900 minutes, package all that and import into SCOM.
First step. Understanding the elements:
Resources:
A file or file of any kind and a resource definition fragment
Write Actions:
Responsible for actually deploying the file to the agent or agents.
Rule:
Needed, to execute the Write Action in a Schedule
Script:
Responsible for taking care of the content on the agent
Let’s go to the steps. If you are not too familiar with Visual Studio Authoring Extensions, please review previous posts on my blog.
In Visual Studio 2012 or 2013, with VSAE installed, create a new solution:

And select as below:

Remember to name it before hitting OK!
Right-click your project name and add 4 new folders:
– Resources
– Scripts
– Write Actions
– Rules
It should look like that.
In the resources folder, right-click and add new Item.

Select Code on the left column then Empty Management Pack Fragment in the center column. Name it Resources.mpx

Replace all of the code with the code below:
<ManagementPackFragment SchemaVersion=”2.0″ xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>
<Resources>
<DeployableResource ID=”ResourceID.testfilesentbySCOM.txt” Accessibility=”Public” FileName=”testfilesentbySCOM.txt” HasNullStream=”false” />
</Resources>
</ManagementPackFragment>
NOTE: the Filename=”xxx” property must match exactly the name of the file that will be in the package.
Right-Click the Resources folder again and click on Add Existing item and add the example text file:

It should look like this:

Now select the text file and change the property as below:

Right-Click the Scripts folder and create a new item.
Select Script as below and name it DeployFile.vbs:

Past the code below:
Option Explicit
Dim fso ‘File System Object
Dim wshShell ‘Windows shell script object
Dim objMOMAPI ‘MOM API object
Dim strScriptName ‘Script name
Dim wshArguments ‘Arguments object
Dim strMsg ‘Generic message variable
Dim strComputerName ‘Computer name
Dim srcFilePath ‘FQPN of source file to be copied to agent target
Dim dirTarget ‘Target folder to place the downloaded bundle file
‘Constants used for event logging with MOM.ScriptAPI
Const INFO = 0
Const C_ERROR = 1
Const WARNING = 2
On Error Resume Next
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set wshShell = CreateObject(“Wscript.Shell”)
Set objMOMAPI = CreateObject(“MOM.ScriptAPI”)
strScriptName = “DeployFile.vbs”
strComputerName = wshShell.ExpandEnvironmentStrings(“%ComputerName%”)
Call objMOMAPI.LogScriptEvent(strScriptName, 999, INFO, “Script started”)
‘Only run this script on a specific server for unit testing
If strComputerName <> “DC01” Then
Call objMOMAPI.LogScriptEvent(strScriptName, 999, INFO, “Unit Testing DC01 not detected”)
wscript.Quit
End If
Set wshArguments = Wscript.Arguments
If wshArguments.Count = 2 Then
srcFilePath = wshArguments(0)
dirTarget = wshArguments(1)
Else
strMsg = “Error: 2 Arguments was expected for this script.” _
& vbCRLF & “Syntax: ” & strScriptName & ” <SourceFilePath> <TargetDirectory>”
Call objMOMAPI.LogScriptEvent(strScriptName, 999, C_INFO, strMsg)
strMsg = “Script ABORTED”
Call objMOMAPI.LogScriptEvent(strScriptName, 999, INFO, strMsg)
wscript.Quit (1)
End If
strMsg = “Will Try to copy file.” _
& vbCRLF & “From: ” & srcFilePath & ” To: ” & dirTarget
Call objMOMAPI.LogScriptEvent(strScriptName, 999, INFO,strMsg)
fso.CopyFile srcFilePath, dirTarget
Call TrapVBScriptError (“FileCopy”)
Sub TrapVBScriptError (ByVal mstrErrorLabel)
If Err.Number <> 0 Then
ErrCount = ErrCount + 1
strMsg = mstrErrorLabel & ” Error ErrNo:” _
& Err.Number & ” ErrDesc: ” & Err.Description
Call objMOMAPI.LogScriptEvent(strScriptName, 999, C_ERROR, strMsg)
Err.Clear
End If
End Sub
‘——————————————–
This a simple script to copy the deployed file from its temporary locating to a controlled folder. Note the piece of code below:
‘Only run this script on a specific server for unit testing
If strComputerName <> “DC01” Then
Call objMOMAPI.LogScriptEvent(strScriptName, 999, INFO, “Unit Testing DC01 not detected”)
wscript.Quit
End If
I have restricted the copy to happen only on one of my agents. You might as well remove it if you want it to be to all the selected targets (see later).
Now Right-Click the Write-Actions folder and add a new item (Empty MP Fragment). Name it: DeployFile.mpx

Replace all the code with the code below:
<ManagementPackFragment SchemaVersion=”2.0″ xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>
<TypeDefinitions>
<ModuleTypes>
<WriteActionModuleType ID=”TextFile.WriteAction.DeployableFile” Accessibility=”Public” Batching=”false”>
<Configuration>
<xsd:element name=”FilePaths” type=”xsd:string” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” />
</Configuration>
<ModuleImplementation Isolation=”Any”>
<Composite>
<MemberModules>
<WriteAction ID=”WA” TypeID=”Windows!Microsoft.Windows.ScriptWriteAction”>
<ScriptName>DeployUR5.vbs</ScriptName>
<Arguments>”$FileResource[Name=”ResourceID.testfilesentbySCOM.txt”]/Path$” “C:\SCOM_Copied_Files\” </Arguments>
<ScriptBody>
$IncludeFileContent/Scripts/DeployFile.vbs$
</ScriptBody>
<TimeoutSeconds>300</TimeoutSeconds>
</WriteAction>
</MemberModules>
<Composition>
<Node ID=”WA” />
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.BaseData</OutputType>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>
</ModuleTypes>
</TypeDefinitions>
<LanguagePacks>
<LanguagePack ID=”ENU” IsDefault=”true”>
<DisplayStrings>
<DisplayString ElementID=”TextFile.WriteAction.DeployableFile”>
<Name>Deploy File Write Action</Name>
<Description>Write action for deploying a file to a SCOM 2012 agent.</Description>
</DisplayString>
</DisplayStrings>
</LanguagePack>
</LanguagePacks>
</ManagementPackFragment>
Note that I’m copying the file to this folder: C:\SCOM_Copied_Files\, which I’m sure exists on my target.
Now, let’s add the rule. This is the most intricate one, let’s go slowly. I could just give you the XML code, but wouldn’t be that fun. So, here we go.
Right-click the rules folder and select Add New item. I have named it FileDeploymentUsingSCOM.FehseRule.DeployTestFile. You can name it Cujo if you want, but I like it descriptive.

After clicking OK, you should see this very intuitive interface…

Click the new rule and note the Properties window on your right (probably):

Let’


Now, for the target. I have picked Microsoft.SystemCenter.Agent, which means everybody except for management servers.

Now will set the Data Sources and Write Actions. Click on the […] box by the Data Sources and then Click Add.

Set the parameters as below:
Property |
Value |
Data Source Type ID |
System!System.SimpleScheduler |
Data Source Configuration |
<IntervalSeconds>300</IntervalSeconds>
<SyncTime></SyncTime>
|
Note the interval : 5 minutes. For testing only, probably.
Now click OK and select the […] by the Write Actions:

Click Add and set the as below:
Property |
Value |
Write Action Type ID |
Click the […] and select TextFile.WriteAction.DeployableFile from the list |
Write Action Configuration |
<FilePaths>$FileResource[Name=’ResourceID.testfilesentbySCOM.txt’]</FilePaths> |
Click OK
Last step in VS is sealing the MP.
Right-click the project and select Properties:

If you don’t have a have, check here on how to do it.
Click on 
Hopefully, you will see this:

Import the MP into SCOM:

Once imported and running you should see this in the event log:

and also, the file in the final location.
Imagine the possibilities, since we can copy anything we want even to servers in a DMZ and execute a script to deal with those files or whatever you need to do.
Hope this helps!