PowerShell Script to Extract CMDB Data From System Center Service Manager Using SDK

Background

In my previous post Writing PowerShell Module That Interact With Various SDK Assemblies, I’ve explained how to create a PowerShell module that embeds various SDK DLLs and I’ve used System Center Service Manager SDK as an example. Well, the reason that I created the module for Service Manager SDK is because I needed to write a script to extract CMDB data from Service Manager. In this post, I’ll go through what’ I’ve done and the script can also be downloaded at the end of the article.

So, I needed to write a script to export configuration items from Service Manager, I have the following requirements:

The script must be generic and extendable to be able to extract instances of any CI classes.

The properties (to be exported) of each class should also be configurable.

After evaluating different options, I have decided to directly interact with Service Manager SDK in the script instead of using the native Service Manager PowerShell module and the community based module SMLets.

Pre-requisite

As I just mentioned, this script requires the SMSDK module I have created previously (you will have to locate the SDK DLLs from your Service Manager management server and copy them to the module folder as I explained in the previous post).

Configuration

In order to make the script generic while being extendable, I’ve used a XML file to define various configurations for the script:

I have added a lot of comments in this XML file so it should be very self-explanatory. Just few notes here:

This XML configuration file must be placed in the same folder as the script.

For each property that you wish to be exported from Service manager, list them under <Properties><PropertyName> tag.

This script also exports the relationships associated with each CI object that is exported. However, only the relationships where the exported CI object is the source object are exported.

Both <PropertyName> and <CIClassName> are the internal names, Please do not use the display names.

You can use the SCSM Entity Explorer (Free download from TechNet Gallery) to identify what are the internal names for the class and property that you wish to export.

Script

Since I have written a lot of scripts using OpsMgr SDK in the past, I didn’t find Service Manager SDK too hard (although this is only the second time I’ve written scripts for Service Manager). The script itself is fairly simple and short:

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

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

#==============================================================

# AUTHOR: Tao Yang

# DATE: 19/02/2015

# Version: 0.1

# Comment: Extract Service Manager 2012 R2 Configuration Items

#==============================================================

Param(

[Parameter(Mandatory=$true)][String]$ManagementServer,

[Parameter(Mandatory=$false)][String]$UserName=$null,

[Parameter(Mandatory=$false)][SecureString]$Password=$null

)

#Import PS Module

#Import-module SMSDK

#Get the current time stamp

$now=Get-Date

$TimeStamp=Get-Date$now-UFormat%d-%m-%y.%H.%M.%S%Z

Write-Verbose"Current Timestamp: $TimeStamp"

$NowFileDateUTC=$now.ToFileTimeUtc()

#Load Config.xml

$thisscript=$MyInvocation.MyCommand.path

$ScriptRoot=Split-Path(Resolve-Path$thisscript)

$configXml=Join-Path$scriptRoot"Config.xml"

Write-Verbose"Reading Configuraiton XML file `'$ConfigXml`'..."

$xml=[xml][/xml](Get-Content$configXml)

$outputDir=$xml.configuration.OutputLocation

$LastSyncFileDateUTC=$xml.configuration.LastSyncFileDateUTC

If($LastSyncFileDateUTC)

{

$LastSyncDate=[datetime]::FromFileTimeUTC($LastSyncFileDateUTC)

Write-Verbose"Last Sync Date (UTC): $LastSyncDate"

$bFullSync=$false

}else{

$LastSyncDate=$Null

Write-Verbose"Last Sync Date is NULL."

$bFullSync=$true

}

Write-Verbose"CI and Relationship exports will be saved in folder `'$OutputDir`'."

#Connect to SCSM Management Group

Write-Verbose"Connecting to System Center Service Manager SDK via server $ManagementServer`..."

To execute the script, simply pass the service management server name (user name and password are optional), and you can also use -verbose if you’d like to see verbose messages:

.\SMConfigItemExtract.ps1 -ManagementServer SCSMMS01 -verbose

Outputs

This script will create a separate CSV file for each CI class that’s configured in the XML. It will also create a single CSV file for ALL relationships export:

The script also writes the execution time stamp to the config.xml under <LastSyncFileDateUTC>. When the script runs next time, it will retrieve this value and only export the configuration items that have been changed after this time stamp. If you need to force a full sync, please manually remove the value in this tag: