-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathNew-MPBFile.ps1
143 lines (135 loc) · 4.72 KB
/
New-MPBFile.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# New-MPBFile.ps1
# this takes files (.mp or .xml) and creates a .mpb file
param (
$mpFile = $( throw "Must have mpfile" ),
[string]$mpbname = "System.Center.Operations.Manager.Health.Check.Reports",
$computername = "localhost"
)
# VARIABLES NEEDED BY SCRIPT
$VerbosePreference = "continue"
$SMDLL = "Microsoft.EnterpriseManagement.Core"
$SMPKG = "Microsoft.EnterpriseManagement.Packaging"
$MPTYPE = "Microsoft.EnterpriseManagement.Configuration.ManagementPack"
$MRESTYPE = "Microsoft.EnterpriseManagement.Configuration.ManagementPackResource"
$SIGTYPE = "Microsoft.EnterpriseManagement.Packaging.ManagementPackBundleStreamSignature"
$FACTYPE = "Microsoft.EnterpriseManagement.Packaging.ManagementPackBundleFactory"
$EMGTYPE = "Microsoft.EnterpriseManagement.EnterpriseManagementGroup"
$OPEN = [System.IO.FileMode]"Open"
$READ = [System.IO.FileAccess]"Read"
# make sure the appropriate assemblies are loaded and retrieve the needed types.
$SMCORE = [reflection.assembly]::LoadWithPartialName($SMDLL)
$SMPACKAGING = [reflection.assembly]::LoadWithPartialName($SMPKG)
$EMPTY = $SMCORE.GetType($SIGTYPE)::Empty
$TYPEOFMP = $SMCORE.GetType($MPTYPE)
$TYPEOFMPR = $SMCORE.GetType($MRESTYPE)
$BFACTORY = $SMPACKAGING.GetType($FACTYPE)
# Functions
# Invoke-GenericMethod
# allows scripts to call generic methods.
# arguments
# mytype - the type inspect for the needed method
# mymethod - the method name
# typearguments - an array of types used by MakeGenericMethod
# object - the object against which invoke is called
# parameters - any parameters needed by invoke
# it returns whatever is returned by invoke
function Invoke-GenericMethod
{
param (
[type]$mytype,
[string]$mymethod,
$TypeArguments,
$object,
[object[]]$parameters = $null
)
$Method = $mytype.GetMethod($mymethod)
$genericMethod = $Method.MakeGenericMethod($TypeArguments)
$genericMethod.Invoke($object,$parameters)
}
# Get-Resources
# this function retrieves resources from the MP. Because our GetResources API
# uses generics, it's a bit tricky to call
# it returns a hash table of the stream, and the name for each resource
# it takes a Management Pack object
function Get-Resources
{
param ( $mpObject )
invoke-GenericMethod $TYPEOFMP "GetResources" $TYPEOFMPR $mpObject | %{
# check to see if we could find the file
$fullname = (resolve-path $_.FileName -ea SilentlyContinue).path
if ( ! $fullname )
{
write-host -for red "
WARNING:
('Cannot find resource: ' + $_.FileName)
Skipping this resource, your MPB will probably not import
Make sure that the resources are in the same directory as the MP"
}
else
{
$stream = new-object io.filestream $fullname,$OPEN,$READ
@{ Stream = $stream; Name = $_.Name }
}
}
}
# Start
# Collect all the mps to add to the mpb!
$mpfileArray = @()
foreach ( $file in $mpFile )
{
foreach ( $item in resolve-path $file )
{
if ( $item.path )
{
$mpfileArray += $item.path
}
else
{
Write-Host -for red "ERROR: Cannot find file $item, skipping"
}
}
}
# Check to see if we have any management packs, if not, exit.
if ( $mpFileArray.Count -eq 0 )
{
Write-Host -for red "Error: No files to add"
exit
}
# we need a connection to the server when we start creating
# the management pack objects
$EMG = new-object $EMGTYPE $computername
# In order to create .mpb, we need to create one
# we'll use the BundleFactory for this
$BUNDLE = $BFACTORY::CreateBundle()
# we'll keep a collection of all the resources that we open
$AllResources = @()
foreach($mpfilepath in $mpfileArray)
{
# This should handle creating mpb from a local file store.
# For now, just create the mp object using the EnterpriseManagementGroup
$theMP = new-object $MPTYPE $mpfilepath,$EMG
Write-Verbose ("Adding MP: " + $theMP.Name)
$BUNDLE.AddManagementPack($theMP)
# Add the resources if any are associated with the MP
$Resources = Get-Resources $theMP
# Add the resources for this MP to the collection
$AllResources += $Resources
if ( $Resources )
{
$Resources | %{
Write-Verbose ("Adding stream: " + $_.Name)
$BUNDLE.AddResourceStream($theMP,$_.Name,$_.Stream,$EMPTY)
}
}
}
# WRITE THE mpb
# First we need a BundleWriter
$bundleWriter = $BFACTORY::CreateBundleWriter(${PWD})
# then we can write out the .mpb
$mpbfullpath = $bundleWriter.Write($BUNDLE,$mpbname)
write-verbose "wrote mpb: $mpbfullpath"
# Cleanup the resources
if ( $AllResources )
{
$AllResources | %{ if ( $_.Stream ) { $_.Stream.Close(); $_.Stream.Dispose() } }
}