├── .gitattributes
├── .github
├── FUNDING.yml
└── stale.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── README.md
└── src
├── Lithnet.ResourceManagement.Automation.Installer
├── Components.wxs
├── Lithnet.ResourceManagement.Automation.Binaries.wxs
├── Lithnet.ResourceManagement.Automation.Installer.wixproj
└── Product.wxs
├── Lithnet.ResourceManagement.Automation.sln
├── Lithnet.ResourceManagement.Automation
├── AttributeValueArrayList.cs
├── ConfigSyncControl.cs
├── Enums
│ ├── ApprovalDecision.cs
│ ├── AttributeOperationType.cs
│ ├── AttributeValueType.cs
│ ├── ResourceOperationType.cs
│ └── SchemaRefreshEvent.cs
├── Examples
│ ├── ChangeLogResource.xml
│ ├── ConfigImportExample.xml
│ ├── Email Notifications
│ │ ├── EmailTemplateAccountExpiry.html
│ │ └── WFAccountExpiry.xoml
│ └── Variables.xml
├── FodyWeavers.xml
├── GetApprovalRequest.cs
├── GetResource.cs
├── GetResourceCount.cs
├── ImportRMConfig.cs
├── Lithnet.ResourceManagement.Automation.csproj
├── LithnetRMA.Help.pshproj
├── LithnetRMA.psd1
├── NewResource.cs
├── NewResourceUpdateTemplate.cs
├── NewXpathExpression.cs
├── NewXpathQuery.cs
├── NewXpathQueryGroup.cs
├── Properties
│ └── AssemblyInfo.cs
├── RemoveResource.cs
├── RmaObject.cs
├── RmaSearchPager.cs
├── RmcWrapper.cs
├── SaveResource.cs
├── SearchResources.cs
├── SearchResourcesPaged.cs
├── SetPendingApprovalRequest.cs
├── SetResourceManagementClient.cs
├── UpdateResourceManagementClientSchema.cs
├── XmlConfig
│ ├── AttributeOperation.cs
│ ├── ConfigFile.cs
│ ├── ResourceOperation.cs
│ ├── Variable.cs
│ └── Variables.cs
├── app.config
├── en-us
│ └── Lithnet.ResourceManagement.Automation.dll-help.xml
├── packages.config
└── packages
│ └── repositories.config
└── Lithnet.ResourceManagement.Resolver
├── Lithnet.ResourceManagement.Resolver.csproj
├── MrmResolver.cs
└── Properties
└── AssemblyInfo.cs
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 | custom: ['https://lithnet.io/donate']
3 |
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | daysUntilStale: 60
3 | # Number of days of inactivity before a stale issue is closed
4 | daysUntilClose: 7
5 | # Issues with these labels will never be considered stale
6 | exemptLabels:
7 | - pinned
8 | - security
9 | # Label to use when marking an issue as stale
10 | staleLabel: stale
11 | # Comment to post when marking an issue as stale. Set to `false` to disable
12 | markComment: >
13 | This issue has been automatically marked as stale because it has not had
14 | recent activity. It will be closed in 7 days if no further activity occurs.
15 | # Comment to post when closing a stale issue. Set to `false` to disable
16 | closeComment: false
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Dd]ebugPublic/
12 | [Rr]elease/
13 | x64/
14 | build/
15 | bld/
16 | [Bb]in/
17 | [Oo]bj/
18 |
19 | # Roslyn cache directories
20 | *.ide/
21 |
22 | # MSTest test Results
23 | [Tt]est[Rr]esult*/
24 | [Bb]uild[Ll]og.*
25 |
26 | #NUNIT
27 | *.VisualState.xml
28 | TestResult.xml
29 |
30 | # Build Results of an ATL Project
31 | [Dd]ebugPS/
32 | [Rr]eleasePS/
33 | dlldata.c
34 |
35 | *_i.c
36 | *_p.c
37 | *_i.h
38 | *.ilk
39 | *.meta
40 | *.obj
41 | *.pch
42 | *.pdb
43 | *.pgc
44 | *.pgd
45 | *.rsp
46 | *.sbr
47 | *.tlb
48 | *.tli
49 | *.tlh
50 | *.tmp
51 | *.tmp_proj
52 | *.log
53 | *.vspscc
54 | *.vssscc
55 | .builds
56 | *.pidb
57 | *.svclog
58 | *.scc
59 |
60 | # Chutzpah Test files
61 | _Chutzpah*
62 |
63 | # Visual C++ cache files
64 | ipch/
65 | *.aps
66 | *.ncb
67 | *.opensdf
68 | *.sdf
69 | *.cachefile
70 |
71 | # Visual Studio profiler
72 | *.psess
73 | *.vsp
74 | *.vspx
75 |
76 | # TFS 2012 Local Workspace
77 | $tf/
78 |
79 | # Guidance Automation Toolkit
80 | *.gpState
81 |
82 | # ReSharper is a .NET coding add-in
83 | _ReSharper*/
84 | *.[Rr]e[Ss]harper
85 | *.DotSettings.user
86 |
87 | # JustCode is a .NET coding addin-in
88 | .JustCode
89 |
90 | # TeamCity is a build add-in
91 | _TeamCity*
92 |
93 | # DotCover is a Code Coverage Tool
94 | *.dotCover
95 |
96 | # NCrunch
97 | _NCrunch_*
98 | .*crunch*.local.xml
99 |
100 | # MightyMoose
101 | *.mm.*
102 | AutoTest.Net/
103 |
104 | # Web workbench (sass)
105 | .sass-cache/
106 |
107 | # Installshield output folder
108 | [Ee]xpress/
109 |
110 | # DocProject is a documentation generator add-in
111 | DocProject/buildhelp/
112 | DocProject/Help/*.HxT
113 | DocProject/Help/*.HxC
114 | DocProject/Help/*.hhc
115 | DocProject/Help/*.hhk
116 | DocProject/Help/*.hhp
117 | DocProject/Help/Html2
118 | DocProject/Help/html
119 |
120 | # Click-Once directory
121 | publish/
122 |
123 | # Publish Web Output
124 | *.[Pp]ublish.xml
125 | *.azurePubxml
126 | ## TODO: Comment the next line if you want to checkin your
127 | ## web deploy settings but do note that will include unencrypted
128 | ## passwords
129 | #*.pubxml
130 |
131 | # NuGet Packages Directory
132 | packages/*
133 | ## TODO: If the tool you use requires repositories.config
134 | ## uncomment the next line
135 | #!packages/repositories.config
136 |
137 | # Enable "build/" folder in the NuGet Packages folder since
138 | # NuGet packages use it for MSBuild targets.
139 | # This line needs to be after the ignore of the build folder
140 | # (and the packages folder if the line above has been uncommented)
141 | !packages/build/
142 |
143 | # Windows Azure Build Output
144 | csx/
145 | *.build.csdef
146 |
147 | # Windows Store app package directory
148 | AppPackages/
149 |
150 | # Others
151 | sql/
152 | *.Cache
153 | ClientBin/
154 | [Ss]tyle[Cc]op.*
155 | ~$*
156 | *~
157 | *.dbmdl
158 | *.dbproj.schemaview
159 | *.pfx
160 | *.publishsettings
161 | node_modules/
162 |
163 | # RIA/Silverlight projects
164 | Generated_Code/
165 |
166 | # Backup & report files from converting an old project file
167 | # to a newer Visual Studio version. Backup files are not needed,
168 | # because we have git ;-)
169 | _UpgradeReport_Files/
170 | Backup*/
171 | UpgradeLog*.XML
172 | UpgradeLog*.htm
173 |
174 | # SQL Server files
175 | *.mdf
176 | *.ldf
177 |
178 | # Business Intelligence projects
179 | *.rdl.data
180 | *.bim.layout
181 | *.bim_*.settings
182 |
183 | # Microsoft Fakes
184 | FakesAssemblies/
185 |
186 | # LightSwitch generated files
187 | GeneratedArtifacts/
188 | _Pvt_Extensions/
189 | ModelManifest.xml
190 | /src/packages
191 |
192 | .vs/
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | https://lithnet.io/contact-us.
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribution guidelines
2 | We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's:
3 |
4 | - Reporting a bug
5 | - Discussing the current state of the code
6 | - Submitting a fix
7 | - Proposing new features
8 |
9 | ## We Develop with Github
10 | We use github to host code, to track issues and feature requests, as well as accept pull requests.
11 |
12 | ## All Code Changes Happen Through Pull Requests
13 | Pull requests are the best way to propose changes to the codebase. We actively welcome your pull requests:
14 |
15 | 1. Fork the repo and create your branch from `master`.
16 | 2. If you've added code that should be tested, add tests.
17 | 3. If you've changed APIs, update the documentation.
18 | 4. Ensure the test suite passes.
19 | 5. Issue the pull request.
20 |
21 | ## Any contributions you make will be under the MIT Software License
22 | In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project.
23 |
24 | ## Report bugs using Github's [issues](https://github.com/lithnet/resourcemanagement-powershell/issues)
25 | We use GitHub issues to track public bugs. Report a bug by [opening a new issue](); it's that easy!
26 |
27 | ## Write bug reports with detail, background, and sample code
28 | The more information we have, the easier it is for us to troubleshoot your issue
29 |
30 | **Great Bug Reports** tend to have:
31 |
32 | - A quick summary and/or background
33 | - Steps to reproduce
34 | - Be specific!
35 | - Give sample code if you can
36 | - What you expected would happen
37 | - What actually happens
38 | - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)
39 |
40 | ## License
41 | By contributing, you agree that your contributions will be licensed under its MIT License.
42 |
43 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Lithnet
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | # FIM/MIM Service PowerShell Module
3 | The Lithnet FIM/MIM Service PowerShell module is designed to make working with the FIM Service faster and easier. It abstracts away the complexity of the FIM Service and the FIMAutomation PowerShell module, and exposes a robust set of cmdlets for creating, updating, deleting and searching for resources.
4 |
5 | ### Guides
6 | * [Installing the module](https://github.com/lithnet/resourcemanagement-powershell/wiki/installing-the-module)
7 | * [Quick reference guide](https://github.com/lithnet/resourcemanagement-powershell/wiki/quick-reference-guide)
8 | * [Working with different data and attribute types](https://github.com/lithnet/resourcemanagement-powershell/wiki/working-with-different-data-and-attribute-types)
9 | * Using the PowerShell module for [configuration management](https://github.com/lithnet/resourcemanagement-powershell/wiki/configuration-management)
10 | * [Cmdlet Reference](https://github.com/lithnet/resourcemanagement-powershell/wiki/cmdlet-reference)
11 |
12 | ### Download the module
13 | Download the [current release](https://github.com/lithnet/resourcemanagement-powershell/releases/)
14 |
15 | ## How can I contribute to the project?
16 | * Found an issue and want us to fix it? [Log it](https://github.com/lithnet/resourcemanagement-powershell/issues)
17 | * Want to fix an issue yourself or add functionality? Clone the project and submit a pull request
18 |
19 | ## Enterprise support
20 | Lithnet offer enterprise support plans for our open-source products. Deploy our tools with confidence that you have the backing of the dedicated Lithnet support team if you run into any issues, have questions, or need advice. Simply fill out the [request form](https://lithnet.io/products/mim), let us know the number of users you are managing with your MIM implementation, and we'll put together a quote.
21 |
22 | ### Keep up to date
23 | * [Visit our blog](http://blog.lithnet.io)
24 | * [Follow us on twitter](https://twitter.com/lithnet_io)
25 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation.Installer/Components.wxs:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation.Installer/Lithnet.ResourceManagement.Automation.Binaries.wxs:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation.Installer/Lithnet.ResourceManagement.Automation.Installer.wixproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 | x64
7 | 3.10
8 | b9eb58e9-c770-4a1a-a4f5-fac5ede1714f
9 | 2.0
10 | Lithnet.ResourceManagement.Automation
11 | Package
12 | $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets
13 | $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets
14 |
15 |
16 | Debug
17 | bin\$(Configuration)\
18 | obj\$(Platform)\$(Configuration)\
19 |
20 |
21 | bin\$(Configuration)\
22 | obj\$(Platform)\$(Configuration)\
23 | True
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | Lithnet.ResourceManagement.Automation
32 | {4c4beb83-82ff-4625-b8c7-d547c654228a}
33 | True
34 | True
35 | Binaries;Content;Satellites
36 | INSTALLFOLDER
37 |
38 |
39 |
40 |
41 | $(WixExtDir)\WixNetFxExtension.dll
42 | WixNetFxExtension
43 |
44 |
45 | $(WixExtDir)\WixUIExtension.dll
46 | WixUIExtension
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | "C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe" sign /sha1 "$(CSCERTTHUMBPRINT)" /t http://timestamp.digicert.com /fd sha256 /v "$(TargetFileName)"
55 |
56 |
64 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation.Installer/Product.wxs:
--------------------------------------------------------------------------------
1 |
2 |
4 |
10 |
11 |
12 |
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 | 1
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 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25123.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lithnet.ResourceManagement.Automation", "Lithnet.ResourceManagement.Automation\Lithnet.ResourceManagement.Automation.csproj", "{4C4BEB83-82FF-4625-B8C7-D547C654228A}"
7 | EndProject
8 | Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Lithnet.ResourceManagement.Automation.Installer", "Lithnet.ResourceManagement.Automation.Installer\Lithnet.ResourceManagement.Automation.Installer.wixproj", "{B9EB58E9-C770-4A1A-A4F5-FAC5EDE1714F}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Debug|Mixed Platforms = Debug|Mixed Platforms
14 | Debug|x86 = Debug|x86
15 | Release|Any CPU = Release|Any CPU
16 | Release|Mixed Platforms = Release|Mixed Platforms
17 | Release|x86 = Release|x86
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {4C4BEB83-82FF-4625-B8C7-D547C654228A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {4C4BEB83-82FF-4625-B8C7-D547C654228A}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {4C4BEB83-82FF-4625-B8C7-D547C654228A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
23 | {4C4BEB83-82FF-4625-B8C7-D547C654228A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
24 | {4C4BEB83-82FF-4625-B8C7-D547C654228A}.Debug|x86.ActiveCfg = Debug|Any CPU
25 | {4C4BEB83-82FF-4625-B8C7-D547C654228A}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {4C4BEB83-82FF-4625-B8C7-D547C654228A}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {4C4BEB83-82FF-4625-B8C7-D547C654228A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
28 | {4C4BEB83-82FF-4625-B8C7-D547C654228A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
29 | {4C4BEB83-82FF-4625-B8C7-D547C654228A}.Release|x86.ActiveCfg = Release|Any CPU
30 | {B9EB58E9-C770-4A1A-A4F5-FAC5EDE1714F}.Debug|Any CPU.ActiveCfg = Debug|x64
31 | {B9EB58E9-C770-4A1A-A4F5-FAC5EDE1714F}.Debug|Mixed Platforms.ActiveCfg = Debug|x64
32 | {B9EB58E9-C770-4A1A-A4F5-FAC5EDE1714F}.Debug|Mixed Platforms.Build.0 = Debug|x64
33 | {B9EB58E9-C770-4A1A-A4F5-FAC5EDE1714F}.Debug|x86.ActiveCfg = Debug|x64
34 | {B9EB58E9-C770-4A1A-A4F5-FAC5EDE1714F}.Release|Any CPU.ActiveCfg = Release|x64
35 | {B9EB58E9-C770-4A1A-A4F5-FAC5EDE1714F}.Release|Mixed Platforms.ActiveCfg = Release|x64
36 | {B9EB58E9-C770-4A1A-A4F5-FAC5EDE1714F}.Release|Mixed Platforms.Build.0 = Release|x64
37 | {B9EB58E9-C770-4A1A-A4F5-FAC5EDE1714F}.Release|x86.ActiveCfg = Release|x64
38 | EndGlobalSection
39 | GlobalSection(SolutionProperties) = preSolution
40 | HideSolutionNode = FALSE
41 | EndGlobalSection
42 | EndGlobal
43 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/AttributeValueArrayList.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Collections;
6 | using System.Management.Automation;
7 | using Lithnet.ResourceManagement.Client;
8 | using Microsoft.ResourceManagement.WebServices;
9 |
10 | namespace Lithnet.ResourceManagement.Automation
11 | {
12 | public class AttributeValueArrayList : ArrayList
13 | {
14 | public AttributeValueArrayList()
15 | : base()
16 | {
17 | }
18 |
19 | public AttributeValueArrayList(ICollection c)
20 | : base(c)
21 | {
22 | }
23 |
24 | public override void AddRange(ICollection c)
25 | {
26 | foreach (object item in c)
27 | {
28 | if (item is RmaObject rmaObject)
29 | {
30 | base.Add(rmaObject.InternalObject.ObjectID);
31 | }
32 | else
33 | {
34 | base.Add(item);
35 | }
36 | }
37 | }
38 |
39 | public override int Add(object value)
40 | {
41 | if (value is RmaObject rmaObject)
42 | {
43 | return base.Add(rmaObject.InternalObject.ObjectID);
44 | }
45 | else
46 | {
47 | return base.Add(value);
48 | }
49 | }
50 |
51 | public override void Remove(object obj)
52 | {
53 | if (base.Contains(obj))
54 | {
55 | // obj is already a unique identifier
56 | base.Remove(obj);
57 | return;
58 | }
59 |
60 | switch (obj)
61 | {
62 | case RmaObject rmaObject:
63 | // obj is an existing object
64 | base.Remove(rmaObject.InternalObject.ObjectID);
65 | return;
66 |
67 | case Guid guid1:
68 | // obj is a guid
69 | base.Remove(new UniqueIdentifier(guid1));
70 | return;
71 |
72 | case string s when Guid.TryParse(s, out Guid guid):
73 | // obj is a string in GUID format
74 | base.Remove(new UniqueIdentifier(guid));
75 | return;
76 | }
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/ConfigSyncControl.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace Lithnet.ResourceManagement.Automation
7 | {
8 | internal static class ConfigSyncControl
9 | {
10 | public static string CurrentPath { get; set; }
11 |
12 | public static ConfigFile CurrentConfig { get; set; }
13 |
14 | public static bool Preview { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/Enums/ApprovalDecision.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Serialization;
6 |
7 | namespace Lithnet.ResourceManagement.Automation
8 | {
9 | public enum ApprovalDecision
10 | {
11 | Approve = 0,
12 |
13 | Reject = 1,
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/Enums/AttributeOperationType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Serialization;
6 |
7 | namespace Lithnet.ResourceManagement.Automation
8 | {
9 | [Flags]
10 | public enum AttributeOperationType
11 | {
12 | [XmlEnum("none")]
13 | None = 0,
14 |
15 | [XmlEnum("add")]
16 | Add = 1,
17 |
18 | [XmlEnum("replace")]
19 | Replace = 2,
20 |
21 | [XmlEnum("delete")]
22 | Delete = 4
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/Enums/AttributeValueType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Serialization;
6 |
7 | namespace Lithnet.ResourceManagement.Automation
8 | {
9 | public enum AttributeValueType
10 | {
11 | [XmlEnum("value")]
12 | Value = 0,
13 |
14 | [XmlEnum("file")]
15 | File = 1,
16 |
17 | [XmlEnum("ref")]
18 | Reference = 2,
19 |
20 | [XmlEnum("xmlref")]
21 | XmlReference = 3,
22 |
23 | [XmlEnum("filter")]
24 | XPathFilter = 4
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/Enums/ResourceOperationType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace Lithnet.ResourceManagement.Automation
7 | {
8 | [Flags]
9 | public enum ResourceOperationType
10 | {
11 | None = 0,
12 | Add = 1,
13 | Update = 2,
14 | Delete = 4
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/Enums/SchemaRefreshEvent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Serialization;
6 |
7 | namespace Lithnet.ResourceManagement.Automation
8 | {
9 | [Flags]
10 | public enum SchemaRefreshEvent
11 | {
12 | [XmlEnum("none")]
13 | None = 0,
14 |
15 | [XmlEnum("before-operation")]
16 | BeforeOperation = 1,
17 |
18 | [XmlEnum("after-operation")]
19 | AfterOperation = 2
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/Examples/ChangeLogResource.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Name
9 |
10 |
11 | changeLogEntry
12 | This resource defines a component and its version within the FIM service
13 | Change Log Entry
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Name
22 |
23 |
24 | version
25 | Version
26 | The current version of the component
27 | Text
28 | false
29 |
30 |
31 |
32 |
33 |
34 | Name
35 |
36 |
37 | details
38 | Details
39 | Contains the change log history for this component
40 | Text
41 | false
42 |
43 |
44 |
45 |
46 |
47 | BoundAttributeType
48 | BoundObjectType
49 |
50 |
51 | changeLogResource
52 | detailsAttribute
53 | false
54 | Details
55 | Contains the change log history for this component
56 |
57 |
58 |
59 |
60 |
61 | BoundAttributeType
62 | BoundObjectType
63 |
64 |
65 | changeLogResource
66 | versionAttribute
67 | false
68 | Version
69 | The current version of the component
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | DisplayName
78 |
79 |
80 | All change log entries
81 | Contains all change log entries
82 | /changeLogEntry
83 |
84 |
85 |
86 |
87 |
88 | DisplayName
89 |
90 |
91 | _Administrators can control change log entries
92 | Allows administrators to read, create, modify and delete change log entries
93 | false
94 | Request
95 |
96 | Modify
97 | Add
98 | Remove
99 | Create
100 | Delete
101 | Read
102 | true
103 | *
104 | Set|DisplayName|Administrators
105 | changeLogEntrySet
106 | changeLogEntrySet
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/Examples/ConfigImportExample.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | DisplayName
14 |
15 |
16 | _Users pending expiration
17 | Contains all accounts with elapsed RS1021 Notification dates, but have not yet expired
18 | /Person[(rs1021NotificationDate < fn:current-dateTime()) and (rs1021Date > fn:current-dateTime()) and Email != '!Invalid!']
19 |
20 |
21 |
22 |
23 |
24 | DisplayName
25 |
26 |
27 | _Account expiration notification to user
28 | An email template used to send a notification to user that their account is about to expire
29 | Notification
30 | .\Email Notifications\EmailTemplateAccountExpiry.html
31 | Your IT account will expire soon
32 |
33 |
34 |
35 |
36 |
37 | DisplayName
38 |
39 |
40 | _Account expiration notification email to user workflow
41 | Sends an account expiry notification email to users email address
42 | .\Email Notifications\WFAccountExpiry.xoml
43 | Action
44 | false
45 |
46 |
47 |
48 |
49 |
50 | DisplayName
51 |
52 |
53 | _Notification - Send account expiration notification email to accounts within the expiration window
54 | Triggers the "##xmlref:accountExpirationWorkflowDefinition:DisplayName##" workflow when a user account transitions into the "##xmlref:accountExpirationSet:DisplayName##" set
55 | *
56 | TransitionIn
57 | accountExpirationWorkflowDefinition
58 | false
59 | false
60 | SetTransition
61 | accountExpirationSet
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | DisplayName
71 |
72 |
73 | FIM Service: Email Notifications
74 | 1.5
75 | RN 05/04/2015
76 | Added DEV5 URL
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/Examples/Email Notifications/EmailTemplateAccountExpiry.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Account expiry notification email
4 |
5 |
6 |
7 |
8 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Dear [//Target/DisplayName],
21 |
22 | Please be advised that your IT account [//Target/AccountName] will expire on:
23 |
24 | [//WorkflowData/aestExpDate] Australian Eastern Standard Time
25 | [//WorkflowData/myExpDate] Malaysian Time
26 | [//WorkflowData/zaExpDate] South African Time
27 |
28 | You will no longer be able to access any IT resources after this date.
29 |
30 | If you have any queries regarding your IT account, please contact your local Service Desk
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
71 |
72 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/Examples/Email Notifications/WFAccountExpiry.xoml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/Examples/Variables.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/GetApprovalRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Management;
6 | using System.Management.Automation;
7 | using Microsoft.ResourceManagement.WebServices;
8 | using System.Collections;
9 | using Lithnet.ResourceManagement.Client;
10 |
11 | namespace Lithnet.ResourceManagement.Automation
12 | {
13 | [Cmdlet(VerbsCommon.Get, "ApprovalRequest")]
14 | public class GetApprovalRequest : PSCmdlet
15 | {
16 | [Parameter(Mandatory = false, Position = 1)]
17 | public ApprovalStatus Status { get; set; }
18 |
19 | protected override void ProcessRecord()
20 | {
21 | ISearchResultCollection results = RmcWrapper.Client.GetApprovals(this.Status);
22 |
23 | foreach (ResourceObject result in results)
24 | {
25 | this.WriteObject(new RmaObject(result));
26 | }
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/GetResource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Management;
6 | using System.Management.Automation;
7 | using Microsoft.ResourceManagement.WebServices;
8 | using System.Collections;
9 | using Lithnet.ResourceManagement.Client;
10 | using System.Globalization;
11 |
12 | namespace Lithnet.ResourceManagement.Automation
13 | {
14 | [Cmdlet(VerbsCommon.Get, "Resource", DefaultParameterSetName = "GetResourceByKey")]
15 | public class GetResource : PSCmdlet //, IDynamicParameters
16 | {
17 | [Parameter(ParameterSetName = "GetResource", ValueFromPipeline = true, Mandatory = true, Position = 1)]
18 | public object ID { get; set; }
19 |
20 | [Parameter(ParameterSetName = "GetResourceByKey", Mandatory = true, ValueFromPipeline = true, Position = 1)]
21 | [Parameter(ParameterSetName = "GetResourceByKeys", Mandatory = true, ValueFromPipeline = true, Position = 1)]
22 | public string ObjectType { get; set; }
23 | //{
24 | // get
25 | // {
26 | // return (string)this.MyInvocation.BoundParameters["ObjectType"];
27 | // }
28 | //}
29 |
30 | [Parameter(ParameterSetName = "GetResourceByKey", Mandatory = true, Position = 2)]
31 | public string AttributeName { get; set; }
32 | //public string AttributeName
33 | //{
34 | // get
35 | // {
36 | // return (string)this.MyInvocation.BoundParameters["AttributeName"];
37 | // }
38 | //}
39 |
40 | [Parameter(ParameterSetName = "GetResourceByKey", Mandatory = true, Position = 3)]
41 | public object AttributeValue { get; set; }
42 |
43 | [Parameter(ParameterSetName = "GetResourceByKeys", Mandatory = true, Position = 2)]
44 | public Hashtable AttributeValuePairs { get; set; }
45 |
46 | [Parameter(ParameterSetName = "GetResourceByKey", Mandatory = false, Position = 4)]
47 | [Parameter(ParameterSetName = "GetResourceByKeys", Mandatory = false, Position = 3)]
48 | [Parameter(ParameterSetName = "GetResource", Mandatory = false, Position = 2)]
49 | public string[] AttributesToGet { get; set; }
50 |
51 | [Parameter(ParameterSetName = "GetResourceByKey", Mandatory = false, Position = 5)]
52 | [Parameter(ParameterSetName = "GetResourceByKeys", Mandatory = false, Position = 4)]
53 | [Parameter(ParameterSetName = "GetResource", Mandatory = false, Position = 3)]
54 | public string Locale { get; set; }
55 |
56 | protected override void ProcessRecord()
57 | {
58 | ResourceObject resource;
59 | CultureInfo locale = null;
60 |
61 | if (this.Locale != null)
62 | {
63 | locale = new CultureInfo(this.Locale);
64 | }
65 |
66 | if (this.ID != null)
67 | {
68 | object item = null;
69 |
70 | if (this.ID is PSObject pso)
71 | {
72 | item = pso.BaseObject;
73 | }
74 | else
75 | {
76 | item = this.ID;
77 | }
78 |
79 | if (item is UniqueIdentifier uniqueID)
80 | {
81 | resource = RmcWrapper.Client.GetResource(uniqueID, this.AttributesToGet, locale);
82 |
83 | if (resource == null)
84 | {
85 | throw new ResourceNotFoundException();
86 | }
87 |
88 | this.WriteObject(new RmaObject(resource));
89 | return;
90 | }
91 |
92 | if (item is string stringID)
93 | {
94 | resource = RmcWrapper.Client.GetResource(stringID, this.AttributesToGet, locale);
95 |
96 | if (resource == null)
97 | {
98 | throw new ResourceNotFoundException();
99 | }
100 |
101 | this.WriteObject(new RmaObject(resource));
102 | return;
103 | }
104 |
105 | if (item is Guid guidID)
106 | {
107 | resource = RmcWrapper.Client.GetResource(guidID, this.AttributesToGet, locale);
108 |
109 | if (resource == null)
110 | {
111 | throw new ResourceNotFoundException();
112 | }
113 |
114 | this.WriteObject(new RmaObject(resource));
115 | return;
116 | }
117 |
118 | throw new ArgumentException($"The object type of the ID parameter was unknown. {this.ID.GetType().FullName}");
119 | }
120 |
121 | if (this.AttributeValuePairs != null)
122 | {
123 | resource = RmcWrapper.Client.GetResourceByKey(this.ObjectType, this.HashTableToDictionary(this.AttributeValuePairs), this.AttributesToGet, locale);
124 |
125 | if (resource == null)
126 | {
127 | throw new ResourceNotFoundException();
128 | }
129 |
130 | this.WriteObject(new RmaObject(resource));
131 | return;
132 | }
133 | else
134 | {
135 | resource = RmcWrapper.Client.GetResourceByKey(this.ObjectType, this.AttributeName, this.AttributeValue, this.AttributesToGet, locale);
136 |
137 | if (resource == null)
138 | {
139 | throw new ResourceNotFoundException();
140 | }
141 |
142 | this.WriteObject(new RmaObject(resource));
143 | return;
144 | }
145 | }
146 |
147 | private Dictionary HashTableToDictionary(Hashtable table)
148 | {
149 | Dictionary dictionary = new Dictionary();
150 |
151 | foreach (DictionaryEntry entry in table)
152 | {
153 | dictionary.Add(entry.Key.ToString(), entry.Value);
154 | }
155 |
156 | return dictionary;
157 | }
158 |
159 | //public object GetDynamicParameters()
160 | //{
161 | // RuntimeDefinedParameterDictionary runtimeDefinedParameterDictionary = new RuntimeDefinedParameterDictionary();
162 | // RuntimeDefinedParameter parameter;
163 |
164 | // parameter = RmcWrapper.GetObjectTypeParameter("ObjectType", true, 1, false, "GetResourceByKey");
165 | // parameter.Attributes.Add(new ParameterAttribute() { ParameterSetName = "GetResourceByKeys", Position = 1, Mandatory = true });
166 | // runtimeDefinedParameterDictionary.Add(parameter.Name, parameter);
167 |
168 | // string objectType = null;
169 | // if (this.MyInvocation.BoundParameters.ContainsKey("ObjectType"))
170 | // {
171 | // objectType = this.ObjectType;
172 | // }
173 |
174 | // parameter = RmcWrapper.GetAttributeNameParameter("AttributeName", true, 2, objectType, "GetResourceByKey");
175 | // runtimeDefinedParameterDictionary.Add(parameter.Name, parameter);
176 |
177 | // return runtimeDefinedParameterDictionary;
178 | //}
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/GetResourceCount.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Management;
6 | using System.Management.Automation;
7 | using Microsoft.ResourceManagement.WebServices;
8 | using System.Collections;
9 | using Lithnet.ResourceManagement.Client;
10 |
11 | namespace Lithnet.ResourceManagement.Automation
12 | {
13 | [Cmdlet(VerbsCommon.Get, "ResourceCount")]
14 | public class GetResourceCount : Cmdlet
15 | {
16 | [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 1)]
17 | public object XPath { get; set; }
18 |
19 | protected override void ProcessRecord()
20 | {
21 | IEnumerable attributes = null;
22 | string filter = this.GetQueryString();
23 | attributes = new List() { "ObjectID" };
24 |
25 | ISearchResultCollection results = RmcWrapper.Client.GetResources(filter, 0, attributes);
26 | this.WriteObject(results.Count);
27 | }
28 |
29 | private string GetQueryString()
30 | {
31 | XPathExpression expression = this.XPath as XPathExpression;
32 |
33 | if (expression != null)
34 | {
35 | return expression.ToString(false);
36 | }
37 |
38 | PSObject wrappedObject = this.XPath as PSObject;
39 |
40 | if (wrappedObject != null)
41 | {
42 | expression = wrappedObject.BaseObject as XPathExpression;
43 |
44 | if (expression != null)
45 | {
46 | return expression.ToString(false);
47 | }
48 |
49 | throw new ArgumentException("The XPath parameter must be a string or XPathExpression object");
50 | }
51 |
52 | if (!(this.XPath is string))
53 | {
54 | throw new ArgumentException("The XPath parameter must be a string or XPathExpression object");
55 | }
56 |
57 | return (string)this.XPath;
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/ImportRMConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Management.Automation;
6 | using System.Xml;
7 | using System.Xml.Serialization;
8 | using System.IO;
9 |
10 | namespace Lithnet.ResourceManagement.Automation
11 | {
12 | [Cmdlet(VerbsData.Import, "RMConfig")]
13 | public class ImportRMConfig : PSCmdlet
14 | {
15 | [Parameter(ValueFromPipeline = false, Mandatory = true, Position = 1)]
16 | public string File { get; set; }
17 |
18 | [Parameter(ValueFromPipeline = false, Mandatory = false, Position = 2)]
19 | public SwitchParameter Preview { get; set; }
20 |
21 | private ConfigFile config;
22 |
23 | protected override void BeginProcessing()
24 | {
25 | this.WriteVerbose("Loading rules file");
26 | XmlSerializer s = new XmlSerializer(typeof(ConfigFile));
27 |
28 | string filename;
29 | string basePath = this.SessionState.Path.CurrentFileSystemLocation.Path;
30 | if (Path.IsPathRooted(this.File))
31 | {
32 | filename = this.File;
33 | }
34 | else
35 | {
36 | filename = Path.Combine(basePath, this.File);
37 | }
38 |
39 | using (StreamReader sr = System.IO.File.OpenText(filename))
40 | {
41 | XmlReader xr = XmlReader.Create(sr);
42 | this.config = (ConfigFile)s.Deserialize(xr);
43 | }
44 |
45 | this.config.Variables.LoadFileVariables(basePath);
46 | ResourceOperation.LogEvent += ResourceOperation_LogEvent;
47 |
48 | ConfigSyncControl.CurrentConfig = this.config;
49 | ConfigSyncControl.CurrentPath = basePath;
50 | ConfigSyncControl.Preview = this.Preview;
51 | }
52 |
53 | protected override void ProcessRecord()
54 | {
55 | int count = 0;
56 |
57 | foreach (ResourceOperation op in this.config.Operations)
58 | {
59 | ProgressRecord p = new ProgressRecord(0, string.Format("Processing import operations{0}...", this.Preview ? " (preview)" : string.Empty)
60 | , string.Format("Processing {0}", op.ID));
61 | p.PercentComplete = (count / this.config.Operations.Count) * 100;
62 | this.WriteProgress(p);
63 | op.ExecuteOperation();
64 | this.WriteVerbose(this.builder.ToString());
65 | this.builder = new StringBuilder();
66 | }
67 | }
68 |
69 | protected override void EndProcessing()
70 | {
71 | ConfigSyncControl.CurrentConfig = null;
72 | }
73 |
74 | private void ResourceOperation_LogEvent(object sender, string e)
75 | {
76 | this.builder.AppendLine(e);
77 | }
78 |
79 | private StringBuilder builder = new StringBuilder();
80 | }
81 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/Lithnet.ResourceManagement.Automation.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {4C4BEB83-82FF-4625-B8C7-D547C654228A}
8 | Library
9 | Properties
10 | Lithnet.ResourceManagement.Automation
11 | Lithnet.ResourceManagement.Automation
12 | v4.5
13 | 512
14 |
15 |
16 |
17 |
18 |
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 | false
27 |
28 |
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 | false
36 |
37 |
38 |
39 | ..\packages\Lithnet.ResourceManagement.Client.1.0.6623.18312\lib\net40\Lithnet.ResourceManagement.Client.dll
40 |
41 |
42 | ..\packages\Lithnet.ResourceManagement.Client.1.0.6623.18312\lib\net40\Microsoft.ResourceManagement.dll
43 | True
44 |
45 |
46 |
47 |
48 |
49 | False
50 | C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll
51 | False
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 | Designer
99 |
100 |
101 | Designer
102 |
103 |
104 |
105 |
106 | PreserveNewest
107 |
108 |
109 |
110 | PreserveNewest
111 |
112 |
113 | Designer
114 |
115 |
116 | Designer
117 |
118 |
119 | Designer
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
140 |
141 |
142 |
143 |
144 |
145 | $(PostBuildEventDependsOn);
146 | PostBuildMacros;
147 |
148 | "C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe" sign /sha1 "$(CSCERTTHUMBPRINT)" /t http://timestamp.digicert.com /fd sha256 /v "$(TargetFileName)"
149 |
150 | "C:\Program Files\Debugging Tools for Windows (x64)\symstore" add /f "$(TargetDir)*.pdb" /s \\localhost\symbols /t "$(ProjectName)" /v "@(VersionNumber)"
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
183 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/LithnetRMA.psd1:
--------------------------------------------------------------------------------
1 | #
2 | # Module manifest for module 'LithnetRMAutomation'
3 | #
4 | # Generated by: Ryan Newington
5 | #
6 | # Generated on: 04/08/2015
7 | #
8 |
9 | @{
10 |
11 | # Version number of this module.
12 | ModuleVersion = '$version$'
13 |
14 | # ID used to uniquely identify this module
15 | GUID = 'd7c36446-aca6-418a-a2a3-cbfc32016a52'
16 |
17 | # Author of this module
18 | Author = 'Ryan Newington'
19 |
20 | # Company or vendor of this module
21 | CompanyName = 'Lithnet'
22 |
23 | # Copyright statement for this module
24 | Copyright = ''
25 |
26 | # Description of the functionality provided by this module
27 | Description = 'Lithnet Resource Management Client for PowerShell'
28 |
29 | # Minimum version of the Windows PowerShell engine required by this module
30 | PowerShellVersion = '3.0'
31 |
32 | # Name of the Windows PowerShell host required by this module
33 | PowerShellHostName = ''
34 |
35 | # Minimum version of the Windows PowerShell host required by this module
36 | PowerShellHostVersion = ''
37 |
38 | # Minimum version of the .NET Framework required by this module
39 | DotNetFrameworkVersion = '4.0'
40 |
41 | # Minimum version of the common language runtime (CLR) required by this module
42 | CLRVersion = ''
43 |
44 | # Processor architecture (None, X86, Amd64, IA64) required by this module
45 | ProcessorArchitecture = 'Amd64'
46 |
47 | # Modules that must be imported into the global environment prior to importing this module
48 | RequiredModules = @()
49 |
50 | # Assemblies that must be loaded prior to importing this module
51 | #RequiredAssemblies = ''
52 |
53 | # Script files (.ps1) that are run in the caller's environment prior to importing this module
54 | ScriptsToProcess = @()
55 |
56 | # Type files (.ps1xml) to be loaded when importing this module
57 | TypesToProcess = @()
58 |
59 | # Format files (.ps1xml) to be loaded when importing this module
60 | FormatsToProcess = @()
61 |
62 | # Modules to import as nested modules of the module specified in ModuleToProcess
63 | NestedModules = 'Lithnet.ResourceManagement.Automation.dll'
64 |
65 | # Functions to export from this module
66 | FunctionsToExport = '*'
67 |
68 | # Cmdlets to export from this module
69 | CmdletsToExport = '*'
70 |
71 | # Variables to export from this module
72 | VariablesToExport = '*'
73 |
74 | # Aliases to export from this module
75 | AliasesToExport = '*'
76 |
77 | # List of all modules packaged with this module
78 | ModuleList = @()
79 |
80 | # List of all files packaged with this module
81 | FileList = @()
82 |
83 | # Private data to pass to the module specified in ModuleToProcess
84 | PrivateData = ''
85 |
86 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/NewResource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Management;
6 | using System.Management.Automation;
7 | using Microsoft.ResourceManagement.WebServices;
8 | using System.Collections;
9 | using Lithnet.ResourceManagement.Client;
10 |
11 | namespace Lithnet.ResourceManagement.Automation
12 | {
13 | [Cmdlet(VerbsCommon.New, "Resource")]
14 | public class NewResource : Cmdlet
15 | {
16 | [Parameter(Mandatory = true, Position = 1)]
17 | public string ObjectType { get; set; }
18 |
19 | protected override void ProcessRecord()
20 | {
21 | this.WriteObject(new RmaObject(RmcWrapper.Client.CreateResource(this.ObjectType)));
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/NewResourceUpdateTemplate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Management;
6 | using System.Management.Automation;
7 | using Microsoft.ResourceManagement.WebServices;
8 | using System.Collections;
9 | using Lithnet.ResourceManagement.Client;
10 |
11 | namespace Lithnet.ResourceManagement.Automation
12 | {
13 | [Cmdlet(VerbsCommon.New, "ResourceUpdateTemplate")]
14 | public class NewResourceUpdateTemplate : Cmdlet
15 | {
16 | [Parameter(Mandatory = true, Position = 1)]
17 | public string ObjectType { get; set; }
18 |
19 | [Parameter(Mandatory = true, Position = 2)]
20 | public object ID { get; set; }
21 |
22 | protected override void ProcessRecord()
23 | {
24 | UniqueIdentifier uniqueID = this.ID as UniqueIdentifier;
25 |
26 | if (uniqueID != null)
27 | {
28 | this.WriteObject(new RmaObject(RmcWrapper.Client.CreateResourceTemplateForUpdate(this.ObjectType, uniqueID)));
29 | return;
30 | }
31 |
32 | string stringID = this.ID as string;
33 |
34 | if (stringID != null)
35 | {
36 | uniqueID = new UniqueIdentifier(stringID);
37 | this.WriteObject(new RmaObject(RmcWrapper.Client.CreateResourceTemplateForUpdate(this.ObjectType, uniqueID)));
38 | return;
39 | }
40 |
41 | Guid? guidID = this.ID as Guid?;
42 |
43 | if (guidID != null)
44 | {
45 | uniqueID = new UniqueIdentifier(guidID.Value);
46 | this.WriteObject(new RmaObject(RmcWrapper.Client.CreateResourceTemplateForUpdate(this.ObjectType, uniqueID)));
47 | return;
48 | }
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/NewXpathExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.ObjectModel;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Management;
7 | using System.Management.Automation;
8 | using Microsoft.ResourceManagement.WebServices;
9 | using System.Collections;
10 | using Lithnet.ResourceManagement.Client;
11 |
12 | namespace Lithnet.ResourceManagement.Automation
13 | {
14 | [Cmdlet(VerbsCommon.New, "XPathExpression")]
15 | public class NewXPathExpression : PSCmdlet //, IDynamicParameters
16 | {
17 | [Parameter(Mandatory = true, Position = 1)]
18 | public string ObjectType {get;set;}
19 | //{
20 | // get
21 | // {
22 | // return (string)this.MyInvocation.BoundParameters["ObjectType"];
23 | // }
24 | //}
25 |
26 | [Parameter(Mandatory = false, Position = 2, ValueFromPipeline = true)]
27 | public IXPathQueryObject QueryObject { get; set; }
28 |
29 | [Parameter(Mandatory = false, Position = 3)]
30 | public string DereferenceAttribute { get; set; }
31 |
32 | [Parameter(Mandatory = false, Position = 4)]
33 | public SwitchParameter WrapFilterXml { get; set; }
34 |
35 | protected override void ProcessRecord()
36 | {
37 | if (this.DereferenceAttribute == null)
38 | {
39 | this.WriteObject(new XPathExpression(this.ObjectType, this.QueryObject, this.WrapFilterXml.IsPresent));
40 | }
41 | else
42 | {
43 | this.WriteObject(new XPathDereferencedExpression(this.ObjectType, this.DereferenceAttribute, this.QueryObject, this.WrapFilterXml.IsPresent));
44 | }
45 | }
46 |
47 | //public object GetDynamicParameters()
48 | //{
49 | // var runtimeDefinedParameterDictionary = new RuntimeDefinedParameterDictionary();
50 | // RuntimeDefinedParameter parameter = RmcWrapper.GetObjectTypeParameter("ObjectType", true, 1, true, null);
51 |
52 | // runtimeDefinedParameterDictionary.Add(parameter.Name, parameter);
53 |
54 | // return runtimeDefinedParameterDictionary;
55 | //}
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/NewXpathQuery.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Management;
6 | using System.Management.Automation;
7 | using Microsoft.ResourceManagement.WebServices;
8 | using System.Collections;
9 | using Lithnet.ResourceManagement.Client;
10 |
11 | namespace Lithnet.ResourceManagement.Automation
12 | {
13 | [Cmdlet(VerbsCommon.New, "XPathQuery")]
14 | public class NewXPathQuery : PSCmdlet//, IDynamicParameters
15 | {
16 | [Parameter(Mandatory = true, Position = 1)]
17 | public string AttributeName {get;set;}
18 | //{
19 | // get
20 | // {
21 | // return (string)this.MyInvocation.BoundParameters["AttributeName"];
22 | // }
23 | //}
24 |
25 | [Parameter(Mandatory = true, Position = 2)]
26 | public ComparisonOperator Operator { get; set; }
27 |
28 | [Parameter(Mandatory = false, Position = 3)]
29 | public object Value { get; set; }
30 |
31 | [Parameter(Mandatory = false, Position = 4)]
32 | public SwitchParameter Negate { get; set; }
33 |
34 | protected override void ProcessRecord()
35 | {
36 | object unwrappedValue;
37 |
38 | PSObject wrappedObject = this.Value as PSObject;
39 |
40 | if (wrappedObject != null)
41 | {
42 | unwrappedValue = wrappedObject.BaseObject;
43 | }
44 | else
45 | {
46 | unwrappedValue = this.Value;
47 | }
48 |
49 | this.WriteObject( new XPathQuery(this.AttributeName, this.Operator, unwrappedValue, this.Negate.IsPresent));
50 | }
51 |
52 |
53 | //public object GetDynamicParameters()
54 | //{
55 | // var runtimeDefinedParameterDictionary = new RuntimeDefinedParameterDictionary();
56 | // RuntimeDefinedParameter parameter = RmcWrapper.GetAttributeNameParameter("AttributeName", true, 1, null, null);
57 |
58 | // runtimeDefinedParameterDictionary.Add(parameter.Name, parameter);
59 |
60 | // return runtimeDefinedParameterDictionary;
61 | //}
62 | }
63 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/NewXpathQueryGroup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Management;
6 | using System.Management.Automation;
7 | using Microsoft.ResourceManagement.WebServices;
8 | using System.Collections;
9 | using Lithnet.ResourceManagement.Client;
10 |
11 | namespace Lithnet.ResourceManagement.Automation
12 | {
13 | [Cmdlet(VerbsCommon.New, "XPathQueryGroup")]
14 | public class NewXPathQueryGroup : Cmdlet
15 | {
16 | [Parameter(Mandatory = true, Position = 1)]
17 | public GroupOperator Operator { get; set; }
18 |
19 | [Parameter(Mandatory = false, Position = 2, ValueFromPipeline = true)]
20 | public IXPathQueryObject[] Queries { get; set; }
21 |
22 | protected override void ProcessRecord()
23 | {
24 | this.WriteObject(new XPathQueryGroup(this.Operator, this.Queries));
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Lithnet PowerShell module for FIM")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Lithnet.ResourceManagement.Automation")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("d195d846-ac23-498c-a45e-88f490d24ab1")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.*")]
36 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/RemoveResource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Management;
6 | using System.Management.Automation;
7 | using Microsoft.ResourceManagement.WebServices;
8 | using System.Collections;
9 | using Lithnet.ResourceManagement.Client;
10 |
11 | namespace Lithnet.ResourceManagement.Automation
12 | {
13 | [Cmdlet(VerbsCommon.Remove, "Resource", DefaultParameterSetName="ObjectIDString")]
14 | public class RemoveResource : Cmdlet
15 | {
16 | [Parameter(Mandatory = true, Position = 1, ParameterSetName = "ID")]
17 | public object[] ID { get; set; }
18 |
19 | [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ParameterSetName = "ResourceObject")]
20 | public RmaObject[] ResourceObjects { get; set; }
21 |
22 | protected override void ProcessRecord()
23 | {
24 | if (this.ID != null)
25 | {
26 | List ids = new List();
27 |
28 | foreach (object id in this.ID)
29 | {
30 | string idString = id as string;
31 | Guid? idGuid = id as Guid?;
32 | UniqueIdentifier idUniqueID = id as UniqueIdentifier;
33 |
34 | if (idString != null)
35 | {
36 | ids.Add(new UniqueIdentifier(idString));
37 | }
38 | else if (idGuid.HasValue)
39 | {
40 | ids.Add(new UniqueIdentifier(idGuid.Value));
41 | }
42 | else if (idUniqueID != null)
43 | {
44 | ids.Add(idUniqueID);
45 | }
46 | }
47 |
48 | RmcWrapper.Client.DeleteResources(ids);
49 | }
50 | else if (this.ResourceObjects != null)
51 | {
52 | RmcWrapper.Client.DeleteResources(this.ResourceObjects.Select(t => t.InternalObject));
53 | }
54 | else
55 | {
56 | throw new InvalidOperationException();
57 | }
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/RmaObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Management.Automation;
7 | using Lithnet.ResourceManagement.Client;
8 |
9 | namespace Lithnet.ResourceManagement.Automation
10 | {
11 | public class RmaObject : PSObject
12 | {
13 | internal RmaObject(ResourceObject resource)
14 | {
15 | this.InternalObject = resource;
16 | this.LoadProperties();
17 | }
18 |
19 | internal ResourceObject InternalObject { get; set; }
20 |
21 | internal void ReloadProperties()
22 | {
23 | foreach (var property in this.Properties)
24 | {
25 | this.Properties.Remove(property.Name);
26 | }
27 |
28 | this.LoadProperties();
29 | }
30 |
31 | private void LoadProperties()
32 | {
33 | foreach (AttributeValue value in this.InternalObject.Attributes.OrderBy(t => t.AttributeName))
34 | {
35 | PSNoteProperty prop;
36 | if (value.Attribute.IsMultivalued)
37 | {
38 | prop = new PSNoteProperty(value.AttributeName, new AttributeValueArrayList((ICollection)value.Value));
39 | }
40 | else
41 | {
42 | prop = new PSNoteProperty(value.AttributeName, value.Value);
43 | }
44 |
45 | this.Properties.Add(prop);
46 | }
47 | }
48 |
49 | internal ResourceObject GetResourceWithAppliedChanges()
50 | {
51 | foreach (var property in this.Properties)
52 | {
53 | if (this.InternalObject.Attributes[property.Name].Attribute.IsReadOnly)
54 | {
55 | continue;
56 | }
57 |
58 | IEnumerable resourceValues = property.Value as IEnumerable;
59 |
60 | if (resourceValues != null)
61 | {
62 | this.SetMultivaluedAttribute(property, resourceValues);
63 | }
64 | else
65 | {
66 | this.SetSingleValuedAttribute(property, property.Value);
67 | }
68 | }
69 |
70 | return this.InternalObject;
71 | }
72 |
73 | private void SetMultivaluedAttribute(PSPropertyInfo property, IEnumerable resourceValues)
74 | {
75 | List newValues = new List();
76 |
77 | foreach (object value in resourceValues)
78 | {
79 | RmaObject resourceValue = value as RmaObject;
80 |
81 | if (resourceValue != null)
82 | {
83 | newValues.Add(resourceValue.InternalObject.ObjectID);
84 | }
85 | else
86 | {
87 | newValues.Add(this.UnwrapPSObject(value));
88 | }
89 | }
90 |
91 | this.InternalObject.Attributes[property.Name].SetValue(newValues);
92 | }
93 |
94 | private void SetSingleValuedAttribute(PSPropertyInfo property, object value)
95 | {
96 | RmaObject resourceValue = property.Value as RmaObject;
97 |
98 | if (resourceValue != null)
99 | {
100 | this.InternalObject.Attributes[property.Name].SetValue(resourceValue.InternalObject.ObjectID);
101 | }
102 | else
103 | {
104 | this.InternalObject.Attributes[property.Name].SetValue(this.UnwrapPSObject(property.Value));
105 | }
106 | }
107 |
108 | private object UnwrapPSObject(object value)
109 | {
110 | PSObject psObject = value as PSObject;
111 |
112 | if (psObject != null)
113 | {
114 | return psObject.BaseObject;
115 | }
116 | else
117 | {
118 | return value;
119 | }
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/RmaSearchPager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using Lithnet.ResourceManagement.Client;
6 |
7 | namespace Lithnet.ResourceManagement.Automation
8 | {
9 | public class RmaSearchPager
10 | {
11 | SearchResultPager pager;
12 |
13 | internal RmaSearchPager(SearchResultPager pager)
14 | {
15 | this.pager = pager;
16 | }
17 |
18 | public int TotalCount
19 | {
20 | get
21 | {
22 | return this.pager.TotalCount;
23 | }
24 | }
25 |
26 | public int CurrentIndex
27 | {
28 | get
29 | {
30 | return this.pager.CurrentIndex;
31 | }
32 | set
33 | {
34 | this.pager.CurrentIndex = value;
35 | }
36 | }
37 |
38 | public int PageSize
39 | {
40 | get
41 | {
42 | return this.pager.PageSize;
43 | }
44 | set
45 | {
46 | this.pager.PageSize = value;
47 | }
48 | }
49 |
50 | public bool HasMoreItems
51 | {
52 | get
53 | {
54 | return this.pager.HasMoreItems;
55 | }
56 | }
57 |
58 | public RmaObject[] GetNextPage()
59 | {
60 | List results = new List();
61 |
62 | foreach(ResourceObject resource in this.pager.GetNextPage())
63 | {
64 | results.Add(new RmaObject(resource));
65 | }
66 |
67 | return results.ToArray();
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/RmcWrapper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using Lithnet.ResourceManagement.Client;
6 | using System.Reflection;
7 | using Microsoft.Win32;
8 | using System.IO;
9 | using System.Management.Automation;
10 |
11 | namespace Lithnet.ResourceManagement.Automation
12 | {
13 | internal static class RmcWrapper
14 | {
15 | private static ResourceManagementClient client;
16 |
17 | public static ResourceManagementClient Client
18 | {
19 | get
20 | {
21 | if (RmcWrapper.client == null)
22 | {
23 | RmcWrapper.client = new ResourceManagementClient();
24 | }
25 |
26 | return RmcWrapper.client;
27 | }
28 |
29 | internal set
30 | {
31 | RmcWrapper.client = value;
32 | }
33 | }
34 |
35 | public static RuntimeDefinedParameter GetObjectTypeParameter(string paramName, bool mandatory, int position, bool allowWildcard, string parameterSetName)
36 | {
37 | RuntimeDefinedParameter parameter = new RuntimeDefinedParameter();
38 | parameter.Name = paramName;
39 | parameter.ParameterType = typeof(string);
40 | IList objectTypes = ResourceManagementSchema.GetObjectTypes().ToList();
41 |
42 | if (objectTypes.Count > 0)
43 | {
44 | List objectTypeNames = objectTypes.OrderBy(t => t.SystemName).Select(t => t.SystemName).ToList();
45 | if (allowWildcard)
46 | {
47 | objectTypeNames.Add("*");
48 | }
49 |
50 | ValidateSetAttribute setAttribute = new ValidateSetAttribute(objectTypeNames.ToArray());
51 | parameter.Attributes.Add(setAttribute);
52 | }
53 |
54 | ParameterAttribute paramAttribute = new ParameterAttribute();
55 | paramAttribute.Mandatory = mandatory;
56 | paramAttribute.Position = position;
57 | paramAttribute.ParameterSetName = parameterSetName;
58 | parameter.Attributes.Add(paramAttribute);
59 | return parameter;
60 | }
61 |
62 | public static RuntimeDefinedParameter GetAttributeNameParameter(string paramName, bool mandatory, int position, string objectType, string parameterSetName)
63 | {
64 | RuntimeDefinedParameter parameter = new RuntimeDefinedParameter();
65 | parameter.Name = paramName;
66 | parameter.ParameterType = typeof(string);
67 |
68 | if (objectType == null)
69 | {
70 | List attributeNames = new List();
71 |
72 | IList objectTypes = ResourceManagementSchema.GetObjectTypes().ToList();
73 |
74 | if (objectTypes.Count > 0)
75 | {
76 | foreach (ObjectTypeDefinition type in objectTypes)
77 | {
78 | attributeNames.AddRange(type.Attributes.Select(t => t.SystemName));
79 | }
80 |
81 | if (attributeNames.Count > 0)
82 | {
83 | ValidateSetAttribute setAttribute = new ValidateSetAttribute(attributeNames.Distinct().OrderBy(t => t).ToArray());
84 | parameter.Attributes.Add(setAttribute);
85 | }
86 | }
87 | }
88 | else
89 | {
90 |
91 | if (ResourceManagementSchema.ContainsObjectType(objectType))
92 | {
93 | ValidateSetAttribute setAttribute = new ValidateSetAttribute(ResourceManagementSchema.GetObjectType(objectType).Attributes.OrderBy(t => t.SystemName).Select(t => t.SystemName).ToArray());
94 | parameter.Attributes.Add(setAttribute);
95 | }
96 | }
97 |
98 | ParameterAttribute paramAttribute = new ParameterAttribute();
99 | paramAttribute.Mandatory = mandatory;
100 | paramAttribute.Position = position;
101 | paramAttribute.ParameterSetName = parameterSetName;
102 | parameter.Attributes.Add(paramAttribute);
103 | return parameter;
104 | }
105 | }
106 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/SaveResource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Management;
6 | using System.Management.Automation;
7 | using Microsoft.ResourceManagement.WebServices;
8 | using System.Collections;
9 | using Lithnet.ResourceManagement.Client;
10 | using System.Globalization;
11 |
12 | namespace Lithnet.ResourceManagement.Automation
13 | {
14 | [Cmdlet(VerbsData.Save, "Resource")]
15 | public class SaveResource : Cmdlet
16 | {
17 | [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 1)]
18 | public RmaObject[] Resources { get; set; }
19 |
20 | [Parameter(Mandatory = false)]
21 | public SwitchParameter Parallel { get; set; }
22 |
23 | [Parameter(Mandatory = false)]
24 | public string Locale { get; set; }
25 |
26 | protected override void ProcessRecord()
27 | {
28 | try
29 | {
30 | IEnumerable creatingObjects = this.Resources.Where(t => t.InternalObject.ModificationType == OperationType.Create).ToList();
31 |
32 | if (this.Locale != null || this.Resources.Any(t => t.InternalObject.Locale != null))
33 | {
34 | CultureInfo locale = null;
35 |
36 | if (this.Locale != null)
37 | {
38 | locale = new CultureInfo(this.Locale);
39 | }
40 |
41 | if (this.Resources.Length > 1)
42 | {
43 | this.WriteWarning("Composite save disabled as locale parameter has been specified or at least one resource has been localized");
44 | }
45 |
46 | foreach (ResourceObject r in this.Resources.Select(t => t.GetResourceWithAppliedChanges()))
47 | {
48 | RmcWrapper.Client.SaveResource(r, locale);
49 | }
50 | }
51 | else
52 | {
53 | if (this.Parallel.IsPresent)
54 | {
55 | RmcWrapper.Client.SaveResourcesParallel(this.Resources.Select(t => t.GetResourceWithAppliedChanges()), -1);
56 | }
57 | else
58 | {
59 | RmcWrapper.Client.SaveResources(this.Resources.Select(t => t.GetResourceWithAppliedChanges()));
60 | }
61 | }
62 |
63 | foreach (RmaObject resource in creatingObjects)
64 | {
65 | resource.ReloadProperties();
66 | }
67 | }
68 | catch (AuthorizationRequiredException ex)
69 | {
70 | this.WriteVerbose("Authorization required: " + ex.ResourceReference);
71 | this.WriteObject(ex.ResourceReference);
72 | }
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/SearchResources.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Management;
6 | using System.Management.Automation;
7 | using Microsoft.ResourceManagement.WebServices;
8 | using Microsoft.ResourceManagement.WebServices.WSEnumeration;
9 | using System.Collections;
10 | using Lithnet.ResourceManagement.Client;
11 | using System.Globalization;
12 |
13 | namespace Lithnet.ResourceManagement.Automation
14 | {
15 | [Cmdlet(VerbsCommon.Search, "Resources", DefaultParameterSetName = "ConstrainedQueryByTypeRaw")]
16 | public class SearchResources : Cmdlet
17 | {
18 | [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 1)]
19 | public object XPath { get; set; }
20 |
21 | [Parameter(ParameterSetName = "ConstrainedQueryByAttributesRaw", Mandatory = false, Position = 2)]
22 | public string[] AttributesToGet { get; set; }
23 |
24 | [Parameter(ParameterSetName = "ConstrainedQueryByTypeRaw", Mandatory = false, Position = 2)]
25 | public string ExpectedObjectType { get; set; }
26 |
27 | [Parameter(ParameterSetName = "UnconstrainedQueryRaw", Mandatory = false, Position = 2)]
28 | public SwitchParameter Unconstrained { get; set; }
29 |
30 | [Parameter]
31 | public int MaxResults { get; set; }
32 |
33 | [Parameter]
34 | public int PageSize { get; set; }
35 |
36 | [Parameter]
37 | public string[] SortAttributes { get; set; }
38 |
39 | [Parameter]
40 | public SwitchParameter Descending { get; set; }
41 |
42 | [Parameter]
43 | public string Locale { get; set; }
44 |
45 | protected override void ProcessRecord()
46 | {
47 | CultureInfo locale = null;
48 |
49 | if (this.Locale != null)
50 | {
51 | locale = new CultureInfo(this.Locale);
52 | }
53 |
54 | IEnumerable attributes = null;
55 | string filter = this.GetQueryString();
56 |
57 | if (!this.Unconstrained.IsPresent)
58 | {
59 | if (this.AttributesToGet == null || this.AttributesToGet.Length == 0)
60 | {
61 | if (string.IsNullOrWhiteSpace(this.ExpectedObjectType))
62 | {
63 | attributes = new List() { "ObjectID" };
64 | }
65 | else
66 | {
67 | ObjectTypeDefinition objectType = ResourceManagementSchema.GetObjectType(this.ExpectedObjectType);
68 | attributes = objectType.Attributes.Select(t => t.SystemName);
69 | }
70 | }
71 | else
72 | {
73 | attributes = this.AttributesToGet;
74 | }
75 | }
76 |
77 | int count = 0;
78 | int pageSize;
79 |
80 | if (this.PageSize > 0)
81 | {
82 | pageSize = this.PageSize;
83 | }
84 | else
85 | {
86 | pageSize = 200;
87 | }
88 |
89 | if (this.MaxResults > 0 && this.MaxResults < pageSize)
90 | {
91 | pageSize = this.MaxResults;
92 | }
93 |
94 | List sortCriteria = new List();
95 | if (this.SortAttributes != null)
96 | {
97 | foreach (string attribute in this.SortAttributes)
98 | {
99 | sortCriteria.Add(new SortingAttribute(attribute, !this.Descending));
100 | }
101 | }
102 |
103 | foreach (ResourceObject resource in RmcWrapper.Client.GetResources(filter, pageSize, attributes, sortCriteria, locale))
104 | {
105 | this.WriteObject(new RmaObject(resource));
106 | count++;
107 |
108 | if (this.MaxResults > 0 && count >= this.MaxResults)
109 | {
110 | break;
111 | }
112 | }
113 | }
114 |
115 | private string GetQueryString()
116 | {
117 | XPathExpression expression = this.XPath as XPathExpression;
118 |
119 | if (expression != null)
120 | {
121 | return expression.ToString(false);
122 | }
123 |
124 | PSObject wrappedObject = this.XPath as PSObject;
125 |
126 | if (wrappedObject != null)
127 | {
128 | expression = wrappedObject.BaseObject as XPathExpression;
129 |
130 | if (expression != null)
131 | {
132 | return expression.ToString(false);
133 | }
134 |
135 | throw new ArgumentException("The XPath parameter must be a string or XPathExpression object");
136 | }
137 |
138 | if (!(this.XPath is string))
139 | {
140 | throw new ArgumentException("The XPath parameter must be a string or XPathExpression object");
141 | }
142 |
143 | return (string)this.XPath;
144 | }
145 | }
146 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/SearchResourcesPaged.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Management;
6 | using System.Management.Automation;
7 | using Microsoft.ResourceManagement.WebServices;
8 | using Microsoft.ResourceManagement.WebServices.WSEnumeration;
9 | using System.Collections;
10 | using Lithnet.ResourceManagement.Client;
11 | using System.Globalization;
12 |
13 | namespace Lithnet.ResourceManagement.Automation
14 | {
15 | [Cmdlet(VerbsCommon.Search, "ResourcesPaged", DefaultParameterSetName = "ConstrainedQueryByTypeRaw")]
16 | public class SearchResourcesPaged : Cmdlet
17 | {
18 | [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 1)]
19 | public object XPath { get; set; }
20 |
21 | [Parameter(ParameterSetName = "ConstrainedQueryByAttributesRaw", Mandatory = false, Position = 2)]
22 | public string[] AttributesToGet { get; set; }
23 |
24 | [Parameter(ParameterSetName = "ConstrainedQueryByTypeRaw", Mandatory = false, Position = 2)]
25 | public string ExpectedObjectType { get; set; }
26 |
27 | [Parameter(ParameterSetName = "UnconstrainedQueryRaw", Mandatory = false, Position = 2)]
28 | public SwitchParameter Unconstrained { get; set; }
29 |
30 | [Parameter]
31 | public int PageSize { get; set; }
32 |
33 | [Parameter]
34 | public string[] SortAttributes { get; set; }
35 |
36 | [Parameter]
37 | public SwitchParameter Descending { get; set; }
38 |
39 | [Parameter]
40 | public string Locale { get; set; }
41 |
42 | protected override void ProcessRecord()
43 | {
44 | CultureInfo locale = null;
45 |
46 | if (this.Locale != null)
47 | {
48 | locale = new CultureInfo(this.Locale);
49 | }
50 |
51 | IEnumerable attributes = null;
52 | string filter = this.GetQueryString();
53 |
54 | if (!this.Unconstrained.IsPresent)
55 | {
56 | if (this.AttributesToGet == null || this.AttributesToGet.Length == 0)
57 | {
58 | if (string.IsNullOrWhiteSpace(this.ExpectedObjectType))
59 | {
60 | attributes = new List() { "ObjectID" };
61 | }
62 | else
63 | {
64 | ObjectTypeDefinition objectType = ResourceManagementSchema.GetObjectType(this.ExpectedObjectType);
65 | attributes = objectType.Attributes.Select(t => t.SystemName);
66 | }
67 | }
68 | else
69 | {
70 | attributes = this.AttributesToGet;
71 | }
72 | }
73 |
74 | int pageSize;
75 |
76 | if (this.PageSize > 0)
77 | {
78 | pageSize = this.PageSize;
79 | }
80 | else
81 | {
82 | pageSize = 200;
83 | }
84 |
85 | List sortCriteria = new List();
86 | if (this.SortAttributes != null)
87 | {
88 | foreach (string attribute in this.SortAttributes)
89 | {
90 | sortCriteria.Add(new SortingAttribute(attribute, !this.Descending));
91 | }
92 | }
93 |
94 | this.WriteObject(new RmaSearchPager(RmcWrapper.Client.GetResourcesPaged(filter, pageSize, attributes, sortCriteria, locale)));
95 | }
96 |
97 | private string GetQueryString()
98 | {
99 | XPathExpression expression = this.XPath as XPathExpression;
100 |
101 | if (expression != null)
102 | {
103 | return expression.ToString(false);
104 | }
105 |
106 | PSObject wrappedObject = this.XPath as PSObject;
107 |
108 | if (wrappedObject != null)
109 | {
110 | expression = wrappedObject.BaseObject as XPathExpression;
111 |
112 | if (expression != null)
113 | {
114 | return expression.ToString(false);
115 | }
116 |
117 | throw new ArgumentException("The XPath parameter must be a string or XPathExpression object");
118 | }
119 |
120 | if (!(this.XPath is string))
121 | {
122 | throw new ArgumentException("The XPath parameter must be a string or XPathExpression object");
123 | }
124 |
125 | return (string)this.XPath;
126 | }
127 | }
128 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/SetPendingApprovalRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Management;
6 | using System.Management.Automation;
7 | using Microsoft.ResourceManagement.WebServices;
8 | using System.Collections;
9 | using Lithnet.ResourceManagement.Client;
10 |
11 | namespace Lithnet.ResourceManagement.Automation
12 | {
13 | [Cmdlet(VerbsCommon.Set, "PendingApprovalRequest")]
14 | public class SetPendingApprovalRequest : PSCmdlet
15 | {
16 | [Parameter(ValueFromPipeline = true, Mandatory = true, Position = 1)]
17 | public RmaObject ApprovalObject { get; set; }
18 |
19 | [Parameter(ValueFromPipeline = false, Mandatory = false, Position = 2)]
20 | public ApprovalDecision Decision { get; set; }
21 |
22 | [Parameter(ValueFromPipeline = false, Mandatory = false, Position = 3)]
23 | public string Reason { get; set; }
24 |
25 | protected override void ProcessRecord()
26 | {
27 | ResourceObject r = this.ApprovalObject.InternalObject;
28 | RmcWrapper.Client.Approve(r, this.Decision == ApprovalDecision.Approve, this.Reason);
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/SetResourceManagementClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Management.Automation;
3 | using System.Net;
4 | using System.Runtime.InteropServices;
5 | using System.Security;
6 | using Lithnet.ResourceManagement.Client;
7 |
8 | namespace Lithnet.ResourceManagement.Automation
9 | {
10 | [Cmdlet(VerbsCommon.Set, "ResourceManagementClient")]
11 | public class SetResourceManagementClient : Cmdlet
12 | {
13 | [Parameter(Mandatory = true, Position = 0)]
14 | public string BaseAddress { get; set; }
15 |
16 | [Parameter(ValueFromPipeline = true, Position = 1)]
17 | public PSCredential Credentials { get; set; }
18 |
19 | [Parameter(Position = 2)]
20 | public string ServicePrincipalName { get; set; }
21 |
22 | [Parameter(Position = 3)]
23 | public bool ForceKerberos { get; set; }
24 |
25 | [Parameter(Position = 4)]
26 | public SwitchParameter RefreshSchema { get; set; }
27 |
28 | protected override void EndProcessing()
29 | {
30 | NetworkCredential creds = null;
31 |
32 | if (this.Credentials != null)
33 | {
34 | creds = this.Credentials.GetNetworkCredential();
35 | }
36 |
37 | Uri baseUri;
38 |
39 | try
40 | {
41 | if (!Uri.TryCreate(this.BaseAddress, UriKind.Absolute, out baseUri))
42 | {
43 | baseUri = new Uri($"http://{this.BaseAddress}:5725");
44 | }
45 | }
46 | catch (Exception ex)
47 | {
48 | this.WriteError(new ErrorRecord(ex, "InvalidUri", ErrorCategory.InvalidArgument, this.BaseAddress));
49 | return;
50 | }
51 |
52 | RmcWrapper.Client = new Client.ResourceManagementClient(baseUri, creds, this.ServicePrincipalName, !this.ForceKerberos);
53 |
54 | if (this.RefreshSchema.IsPresent || !baseUri.Host.Equals(ResourceManagementSchema.SchemaEndpoint?.Host, StringComparison.OrdinalIgnoreCase))
55 | {
56 | RmcWrapper.Client.RefreshSchema();
57 | }
58 |
59 | base.EndProcessing();
60 | }
61 |
62 | private string ConvertToUnsecureString(SecureString securePassword)
63 | {
64 | if (securePassword == null)
65 | throw new ArgumentNullException(nameof(securePassword));
66 |
67 | IntPtr unmanagedString = IntPtr.Zero;
68 | try
69 | {
70 | unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(securePassword);
71 | return Marshal.PtrToStringUni(unmanagedString);
72 | }
73 | finally
74 | {
75 | Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
76 | }
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/UpdateResourceManagementClientSchema.cs:
--------------------------------------------------------------------------------
1 |
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Management;
7 | using System.Management.Automation;
8 | using Microsoft.ResourceManagement.WebServices;
9 | using System.Collections;
10 | using Lithnet.ResourceManagement.Client;
11 |
12 | namespace Lithnet.ResourceManagement.Automation
13 | {
14 | [Cmdlet(VerbsData.Update, "ResourceManagementClientSchema")]
15 | public class UpdateResourceManagementClientSchema : Cmdlet
16 | {
17 | protected override void ProcessRecord()
18 | {
19 | RmcWrapper.Client.RefreshSchema();
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/XmlConfig/AttributeOperation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Serialization;
6 | using System.IO;
7 | using Lithnet.ResourceManagement.Client;
8 | using System.Globalization;
9 | using System.Text.RegularExpressions;
10 | using Microsoft.ResourceManagement.WebServices;
11 | using System.Security;
12 |
13 | namespace Lithnet.ResourceManagement.Automation
14 | {
15 | public class AttributeOperation
16 | {
17 | private const string filterTextFormat = "{0} ";
18 |
19 | [XmlAttribute(AttributeName = "operation")]
20 | public AttributeOperationType Operation { get; set; }
21 |
22 | [XmlAttribute(AttributeName = "name")]
23 | public string Name { get; set; }
24 |
25 | [XmlAttribute(AttributeName = "type")]
26 | public AttributeValueType ValueType { get; set; }
27 |
28 | [XmlText()]
29 | public string Value { get; set; }
30 |
31 | [XmlIgnore]
32 | public object ExpandedValue
33 | {
34 | get
35 | {
36 | return this.GetValue();
37 | }
38 | }
39 |
40 | internal void ExecuteOperation(ResourceObject resource, ResourceOperationType resourceOpType)
41 | {
42 | if (resource == null)
43 | {
44 | throw new ArgumentNullException("resource");
45 | }
46 |
47 | this.ValidateResourceOperationType(resourceOpType);
48 |
49 | switch (this.Operation)
50 | {
51 | case AttributeOperationType.None:
52 | return;
53 |
54 | case AttributeOperationType.Add:
55 | this.PerformAttributeAdd(resource);
56 | break;
57 |
58 | case AttributeOperationType.Replace:
59 | this.PerformAttributeReplace(resource);
60 | break;
61 |
62 | case AttributeOperationType.Delete:
63 | this.PerformAttributeDelete(resource);
64 | break;
65 |
66 | default:
67 | throw new ArgumentException("Unknown or unsupported operation type");
68 | }
69 | }
70 |
71 | private void PerformAttributeAdd(ResourceObject resource)
72 | {
73 | if (!resource.Attributes[this.Name].Attribute.IsMultivalued)
74 | {
75 | this.PerformAttributeReplace(resource);
76 | }
77 | else
78 | {
79 | object newValue = this.ExpandedValue;
80 |
81 | resource.Attributes[this.Name].AddValue(newValue);
82 | }
83 | }
84 |
85 | private void PerformAttributeReplace(ResourceObject resource)
86 | {
87 | object newValue = this.ExpandedValue;
88 |
89 | if (newValue is string)
90 | {
91 | if (string.IsNullOrEmpty((string)newValue))
92 | {
93 | if (resource.Attributes[this.Name].IsNull)
94 | {
95 | return;
96 | }
97 | }
98 | }
99 |
100 | resource.Attributes[this.Name].SetValue(newValue);
101 | }
102 |
103 | private void PerformAttributeDelete(ResourceObject resource)
104 | {
105 | object newValue = this.ExpandedValue;
106 |
107 | resource.Attributes[this.Name].RemoveValue(newValue);
108 | }
109 |
110 | private void ValidateResourceOperationType(ResourceOperationType resourceOpType)
111 | {
112 | switch (this.Operation)
113 | {
114 | case AttributeOperationType.None:
115 | break;
116 |
117 | case AttributeOperationType.Replace:
118 | case AttributeOperationType.Delete:
119 | case AttributeOperationType.Add:
120 | if (resourceOpType == ResourceOperationType.Delete)
121 | {
122 | throw new ArgumentException("Cannot perform an attribute change on a delete operation");
123 | }
124 |
125 | break;
126 |
127 | default:
128 | throw new ArgumentException("Unknown or unsupported AttributeOperationType: " + this.Operation.ToString());
129 | }
130 | }
131 |
132 | private object GetValue()
133 | {
134 | if (this.Value == null)
135 | {
136 | return null;
137 | }
138 |
139 | switch (this.ValueType)
140 | {
141 | case AttributeValueType.Value:
142 | return this.ExpandVariables(this.Value);
143 |
144 | case AttributeValueType.File:
145 | return this.GetFileContent(this.ExpandVariables(this.Value));
146 |
147 | case AttributeValueType.Reference:
148 | return this.GetReference(this.Value);
149 |
150 | case AttributeValueType.XmlReference:
151 | return this.GetXmlReference(this.Value);
152 |
153 | case AttributeValueType.XPathFilter:
154 | return this.BuildFilterAttribute(this.Value);
155 |
156 | default:
157 | throw new ArgumentException("Unknown value type " + this.Value.ToString());
158 | }
159 | }
160 |
161 | private string ExpandVariables(string input)
162 | {
163 | string expandedInput = input;
164 |
165 | if ( ConfigSyncControl.CurrentConfig.Variables != null && ConfigSyncControl.CurrentConfig.Variables.Items != null)
166 | {
167 | foreach (Variable variable in ConfigSyncControl.CurrentConfig.Variables.Items)
168 | {
169 | expandedInput = expandedInput.Replace(variable.Name, variable.ExpandedValue);
170 | }
171 | }
172 |
173 | foreach (Match match in Regex.Matches(expandedInput, @"\#\#xmlref:(.+?):(.*?)\#\#"))
174 | {
175 | if (match.Groups.Count >= 2)
176 | {
177 | string xmlRefName = match.Groups[1].Value;
178 | ResourceObject xmlRef = this.GetXmlReferenceResource(xmlRefName);
179 | if (xmlRef == null)
180 | {
181 | throw new ArgumentException("The input string contained the xmlref pattern '{0}', but the object could not be resolved");
182 | }
183 |
184 | string xmlDeRefAttributeName = "ObjectID";
185 | if (match.Groups.Count > 2)
186 | {
187 | string groupValue = match.Groups[2].Value;
188 |
189 | if (!string.IsNullOrWhiteSpace(groupValue))
190 | {
191 | xmlDeRefAttributeName = match.Groups[2].Value;
192 | }
193 | }
194 |
195 | object xmlDeRefValue = xmlRef.Attributes[xmlDeRefAttributeName].Value;
196 |
197 | UniqueIdentifier xmlDerefID = xmlDeRefValue as UniqueIdentifier;
198 | if (xmlDerefID != null)
199 | {
200 | xmlDeRefValue = xmlDerefID.Value;
201 | }
202 |
203 | expandedInput = expandedInput.Replace(match.Value, xmlDeRefValue == null ? null : xmlDeRefValue.ToString());
204 | }
205 | }
206 |
207 | return expandedInput;
208 | }
209 |
210 | private string GetFileContent(string filename)
211 | {
212 | if (!Path.IsPathRooted(filename))
213 | {
214 | filename = Path.Combine(ConfigSyncControl.CurrentPath, filename);
215 | }
216 |
217 | return this.ExpandVariables(File.ReadAllText(filename));
218 | }
219 |
220 | private string BuildFilterAttribute(string xpath)
221 | {
222 | string unescapedText = this.ExpandVariables(xpath);
223 | string escapedText = unescapedText.Replace("<", "<").Replace(">", ">");
224 | string returnValue = string.Format(filterTextFormat, escapedText);
225 | return returnValue;
226 | }
227 |
228 | private string GetReference(string value)
229 | {
230 | string[] split = this.ExpandVariables(value).Split('|');
231 | if (split.Length != 3)
232 | {
233 | throw new ArgumentException(string.Format("The attribute operation of {0} on attribute {1} specifies a reference type, but does not have a string in the value of ObjectType|AttributeName|AttributeValue. The invalid value was {2}", this.Name, this.Operation, this.Value));
234 | }
235 |
236 | ResourceObject resource = RmcWrapper.Client.GetResourceByKey(split[0], split[1], split[2], ResourceManagementSchema.GetObjectType(split[0]).Attributes.Select(t => t.SystemName).Except(ResourceManagementSchema.ComputedAttributes));
237 |
238 | if (resource == null)
239 | {
240 | if (ConfigSyncControl.Preview)
241 | {
242 | return Guid.NewGuid().ToString();
243 | }
244 | else
245 | {
246 | throw new ArgumentException(string.Format("The attribute operation of {1} on attribute {0} specifies a reference to {2}, but the object was not found in the FIM service", this.Name, this.Operation, value));
247 | }
248 | }
249 |
250 | return resource.ObjectID.Value;
251 | }
252 |
253 | private string GetXmlReference(string id)
254 | {
255 | ResourceObject resource = this.GetXmlReferenceResource(id);
256 |
257 | return resource.ObjectID == null ? Guid.Empty.ToString() : resource.ObjectID.Value;
258 | }
259 |
260 | private ResourceObject GetXmlReferenceResource(string id)
261 | {
262 | ResourceOperation op = ConfigSyncControl.CurrentConfig.Operations.FirstOrDefault(t => t.ID == id);
263 |
264 | if (op == null)
265 | {
266 | throw new ArgumentException(string.Format("The attribute operation of {1} on attribute {0} specifies a reference to another operation with ID {2}, but the operation was not found in the XML file", this.Name, this.Operation, id));
267 | }
268 |
269 | if (op.HasProcessed)
270 | {
271 | return op.Resource;
272 | }
273 |
274 | Dictionary anchorValues;
275 |
276 | try
277 | {
278 | anchorValues = op.GetAnchorValues();
279 | }
280 | catch (Exception ex)
281 | {
282 | throw new ArgumentException(string.Format("The attribute operation of {1} on attribute {0} specifies a reference to another operation with ID {2}, but resource failed to resolve its anchor", this.Name, this.Operation, id), ex);
283 | }
284 |
285 | ResourceObject resource = RmcWrapper.Client.GetResourceByKey(op.ResourceType, anchorValues, op.AttributesToGet);
286 |
287 | if (resource == null)
288 | {
289 | throw new ArgumentException(string.Format("The attribute operation of {1} on attribute {0} specifies a reference to another operation with ID {2}, but the object was not found in the FIM service", this.Name, this.Operation, id));
290 | }
291 |
292 | return resource;
293 | }
294 | }
295 | }
296 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/XmlConfig/ConfigFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Serialization;
6 |
7 | namespace Lithnet.ResourceManagement.Automation
8 | {
9 | [XmlRoot(ElementName = "Lithnet.ResourceManagement.ConfigSync")]
10 | public class ConfigFile
11 | {
12 | private Variables variables;
13 | private List operations;
14 |
15 | public Variables Variables
16 | {
17 | get
18 | {
19 | if (this.variables == null)
20 | {
21 | this.variables = new Variables();
22 | }
23 |
24 | return this.variables;
25 | }
26 | set
27 | {
28 | this.variables = value;
29 | }
30 | }
31 |
32 | [XmlArray(ElementName = "Operations")]
33 | [XmlArrayItem(ElementName = "ResourceOperation", Type = typeof(ResourceOperation))]
34 | public List Operations
35 | {
36 | get
37 | {
38 | if (this.operations == null)
39 | {
40 | this.operations = new List();
41 | }
42 |
43 | return this.operations;
44 | }
45 | set
46 | {
47 | this.operations = value;
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/XmlConfig/ResourceOperation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Serialization;
6 | using System.Collections.ObjectModel;
7 | using System.Collections;
8 | using Lithnet.ResourceManagement.Client;
9 | using System.Globalization;
10 |
11 | namespace Lithnet.ResourceManagement.Automation
12 | {
13 | public class ResourceOperation
14 | {
15 | public delegate void LogMessageEventHander(object sender, string message);
16 |
17 | internal static event LogMessageEventHander LogEvent;
18 |
19 | private List anchorAttributes;
20 |
21 | private List attributeOperations;
22 |
23 | [XmlArray(ElementName = "AnchorAttributes", IsNullable = true)]
24 | [XmlArrayItem(ElementName = "AnchorAttribute", IsNullable = false)]
25 | public List AnchorAttributes
26 | {
27 | get
28 | {
29 | if (this.anchorAttributes == null)
30 | {
31 | this.anchorAttributes = new List();
32 | }
33 |
34 | return this.anchorAttributes;
35 | }
36 | set
37 | {
38 | this.anchorAttributes = value;
39 | }
40 | }
41 |
42 | [XmlArray(ElementName = "AttributeOperations", IsNullable = true)]
43 | [XmlArrayItem(ElementName = "AttributeOperation", IsNullable = false)]
44 | public List AttributeOperations
45 | {
46 | get
47 | {
48 | if (this.attributeOperations == null)
49 | {
50 | this.attributeOperations = new List();
51 | }
52 |
53 | return this.attributeOperations;
54 | }
55 | set
56 | {
57 | this.attributeOperations = value;
58 | }
59 | }
60 |
61 | [XmlAttribute(AttributeName = "operation")]
62 | public ResourceOperationType Operation { get; set; }
63 |
64 | [XmlAttribute(AttributeName = "resourceType")]
65 | public string ResourceType { get; set; }
66 |
67 | [XmlAttribute(AttributeName = "locale")]
68 | public string Locale { get; set; }
69 |
70 | [XmlAttribute(AttributeName = "id")]
71 | public string ID { get; set; }
72 |
73 | [XmlAttribute(AttributeName = "refresh-schema")]
74 | public SchemaRefreshEvent SchemaRefresh { get; set; }
75 |
76 | [XmlIgnore]
77 | public string ObjectID
78 | {
79 | get
80 | {
81 | if (this.Resource != null && this.Resource.ObjectID != null)
82 | {
83 | return this.Resource.ObjectID.Value;
84 | }
85 | else
86 | {
87 | return null;
88 | }
89 | }
90 | }
91 |
92 | [XmlIgnore]
93 | internal bool HasProcessed
94 | {
95 | get
96 | {
97 | return this.Resource != null;
98 | }
99 | }
100 |
101 | [XmlIgnore]
102 | internal ResourceObject Resource { get; private set; }
103 |
104 | internal void ExecuteOperation()
105 | {
106 | if (this.SchemaRefresh == SchemaRefreshEvent.BeforeOperation)
107 | {
108 | this.RaiseLogEvent("Refreshing schema");
109 | RmcWrapper.Client.RefreshSchema();
110 | }
111 |
112 | this.ThrowOnLocaleSpecifiedForNonUpdate();
113 |
114 | switch (this.Operation)
115 | {
116 | case ResourceOperationType.None:
117 | break;
118 |
119 | case ResourceOperationType.Add:
120 | this.ProcessResourceAdd();
121 | break;
122 |
123 | case ResourceOperationType.Update:
124 | this.ProcessResourceUpdate();
125 | break;
126 |
127 | case ResourceOperationType.Delete:
128 | this.ProcessResourceDelete();
129 | break;
130 |
131 | case ResourceOperationType.Add | ResourceOperationType.Update:
132 | this.ProcessResourceAddUpdate();
133 | break;
134 |
135 | default:
136 | throw new ArgumentException("Unknown or unsupported operation type: " + this.Operation.ToString());
137 | }
138 |
139 | if (this.SchemaRefresh == SchemaRefreshEvent.AfterOperation)
140 | {
141 | this.RaiseLogEvent("Refreshing schema");
142 | RmcWrapper.Client.RefreshSchema();
143 | }
144 | }
145 |
146 | private void ThrowOnLocaleSpecifiedForNonUpdate()
147 | {
148 | if (this.Locale != null)
149 | {
150 | if (this.Operation != ResourceOperationType.Update)
151 | {
152 | throw new InvalidOperationException("Locale can only be specified for an 'Update' operation. Perform an Add-Update first with the invariant culture values, then perform an update with the culture-specific values");
153 | }
154 | }
155 | }
156 |
157 | private void ProcessResourceAdd()
158 | {
159 | this.Resource = RmcWrapper.Client.CreateResource(this.ResourceType);
160 | this.ExecuteAttributeOperations();
161 |
162 | this.RaiseLogEvent(string.Format("Creating resource {0} with the following attribute values", this.ID));
163 |
164 | foreach (AttributeValue attribute in this.Resource.Attributes)
165 | {
166 | this.RaiseLogEvent(string.Format("{0}:{1}", attribute.AttributeName, attribute.ToString()));
167 | }
168 |
169 | if (!ConfigSyncControl.Preview)
170 | {
171 | this.Resource.Save();
172 | }
173 | }
174 |
175 | private void ProcessResourceUpdate()
176 | {
177 | if (this.Resource == null)
178 | {
179 | CultureInfo locale = null;
180 |
181 | if (!string.IsNullOrWhiteSpace(this.Locale))
182 | {
183 | locale = new CultureInfo(this.Locale);
184 | }
185 |
186 | this.Resource = RmcWrapper.Client.GetResourceByKey(this.ResourceType, this.GetAnchorValues(), this.AttributesToGet, locale);
187 |
188 | if (this.Resource == null)
189 | {
190 | throw new InvalidOperationException(string.Format("An update operation is not valid for the resource operation with ID {0} as the resource does not exist in the FIM service. Consider changing the operation to an 'Add Update' type", this.ID));
191 | }
192 | }
193 |
194 | this.ExecuteAttributeOperations();
195 |
196 | Dictionary> attributeChanges = this.Resource.PendingChanges;
197 |
198 | if (attributeChanges.Count == 0)
199 | {
200 | this.RaiseLogEvent(string.Format("Object {0} was up to date", this.ID));
201 | }
202 | else
203 | {
204 | this.RaiseLogEvent(string.Format("Updating resource {0} with the following attribute values", this.ID));
205 |
206 | foreach (KeyValuePair> attributeChange in attributeChanges)
207 | {
208 | foreach (AttributeValueChange valueChange in attributeChange.Value)
209 | {
210 | this.RaiseLogEvent(string.Format("{0}:{1}:{2}", attributeChange.Key, valueChange.ChangeType, valueChange.Value == null ? string.Empty : valueChange.Value.ToString()));
211 | }
212 | }
213 |
214 | if (!ConfigSyncControl.Preview)
215 | {
216 | this.Resource.Save();
217 | }
218 | }
219 | }
220 |
221 | private void ProcessResourceDelete()
222 | {
223 | if (this.Resource == null)
224 | {
225 | this.Resource = RmcWrapper.Client.GetResourceByKey(this.ResourceType, this.GetAnchorValues(), new List() { "ObjectID" });
226 |
227 | if (this.Resource == null)
228 | {
229 | this.RaiseLogEvent(string.Format("The object {0} was not found in the FIM service", this.ID));
230 | return;
231 | }
232 | }
233 |
234 | this.RaiseLogEvent(string.Format("Deleting object {0}-{1}", this.ID, this.ObjectID));
235 |
236 | if (!ConfigSyncControl.Preview)
237 | {
238 | RmcWrapper.Client.DeleteResource(this.Resource);
239 | }
240 | }
241 |
242 | private void ProcessResourceAddUpdate()
243 | {
244 | this.Resource = RmcWrapper.Client.GetResourceByKey(this.ResourceType, this.GetAnchorValues(), this.AttributesToGet);
245 |
246 | if (this.Resource == null)
247 | {
248 | this.ProcessResourceAdd();
249 | }
250 | else
251 | {
252 | this.ProcessResourceUpdate();
253 | }
254 | }
255 |
256 | internal Dictionary GetAnchorValues()
257 | {
258 | Dictionary anchors = new Dictionary();
259 |
260 | foreach (string anchor in this.AnchorAttributes)
261 | {
262 | if (string.IsNullOrWhiteSpace(anchor))
263 | {
264 | throw new ArgumentException(string.Format("The resource operation with ID {0} specified a modification type that requires an anchor, but no anchor attributes were present"));
265 | }
266 |
267 | AttributeOperation attributeOp = this.AttributeOperations.FirstOrDefault(t => t.Name == anchor);
268 |
269 | if (attributeOp == null)
270 | {
271 | throw new ArgumentException(
272 | string.Format(
273 | "The resource operation with ID {0} specified a modification type that requires an anchor, but the defined anchor attribute was not present in the list of AttributeOperations",
274 | this.ID));
275 | }
276 |
277 | anchors.Add(anchor, attributeOp.ExpandedValue.ToString());
278 | }
279 |
280 | return anchors;
281 | }
282 |
283 | internal IEnumerable AttributesToGet
284 | {
285 | get
286 | {
287 | List attributesToGet = new List();
288 |
289 | foreach (string anchor in this.AnchorAttributes)
290 | {
291 | attributesToGet.Add(anchor);
292 | }
293 |
294 | foreach (AttributeOperation op in this.AttributeOperations)
295 | {
296 | attributesToGet.Add(op.Name);
297 | }
298 |
299 | return attributesToGet.Distinct();
300 | }
301 | }
302 |
303 | private void ExecuteAttributeOperations()
304 | {
305 | foreach (AttributeOperation op in this.AttributeOperations)
306 | {
307 | op.ExecuteOperation(this.Resource, this.Operation);
308 | }
309 | }
310 |
311 | private void RaiseLogEvent(string message)
312 | {
313 | if (ResourceOperation.LogEvent != null)
314 | {
315 | ResourceOperation.LogEvent(this, message);
316 | }
317 | }
318 | }
319 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/XmlConfig/Variable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Serialization;
6 |
7 | namespace Lithnet.ResourceManagement.Automation
8 | {
9 | public class Variable
10 | {
11 | [XmlAttribute("name")]
12 | public string Name { get; set; }
13 |
14 | [XmlAttribute("value")]
15 | public string Value { get; set; }
16 |
17 | [XmlIgnore]
18 | public string ExpandedValue
19 | {
20 | get
21 | {
22 | return Environment.ExpandEnvironmentVariables(this.Value);
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/XmlConfig/Variables.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Xml.Serialization;
6 | using System.IO;
7 | using System.Xml;
8 | using System.Collections;
9 |
10 | namespace Lithnet.ResourceManagement.Automation
11 | {
12 | [XmlRoot(ElementName = "Lithnet.ResourceManagement.ConfigSync.Variables")]
13 | [XmlType("Variables")]
14 | public class Variables
15 | {
16 | [XmlAttribute("import-file")]
17 | public string FileName { get; set; }
18 |
19 | [XmlElement("Variable")]
20 | public List Items { get; set; }
21 |
22 | internal void LoadFileVariables(string currentPath)
23 | {
24 | if (!string.IsNullOrWhiteSpace(this.FileName))
25 | {
26 | XmlSerializer s = new XmlSerializer(typeof(Variables));
27 |
28 | string filename;
29 |
30 | if (Path.IsPathRooted(this.FileName))
31 | {
32 | filename = this.FileName;
33 | }
34 | else
35 | {
36 | filename = Path.Combine(currentPath, this.FileName);
37 | }
38 |
39 | StreamReader sr = File.OpenText(filename);
40 | XmlReader xr = XmlReader.Create(sr);
41 | Variables variables = (Variables)s.Deserialize(xr);
42 |
43 | variables.LoadFileVariables(currentPath);
44 |
45 | foreach (Variable variable in variables.Items)
46 | {
47 | this.Items.Add(variable);
48 | }
49 | }
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Automation/packages/repositories.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Resolver/Lithnet.ResourceManagement.Resolver.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {D93AB9DD-9953-4E78-B247-DD5C89097844}
8 | Library
9 | Properties
10 | Lithnet.ResourceManagement.Resolver
11 | Lithnet.ResourceManagement.Resolver
12 | v4.0
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | C:\Windows\Sysnative\WindowsPowerShell\v1.0\Modules\LithnetRMA\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
53 |
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Resolver/MrmResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Reflection;
6 |
7 | namespace Lithnet.ResourceManagement.Resolver
8 | {
9 | public static class MrmResolver
10 | {
11 | private static int loadAttempts;
12 |
13 | public static void RegisterResolver()
14 | {
15 | AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
16 | }
17 |
18 | private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
19 | {
20 | if (args.Name.StartsWith("Microsoft.ResourceManagement"))
21 | {
22 | loadAttempts++;
23 |
24 | if (loadAttempts > 1)
25 | {
26 | return null;
27 | }
28 |
29 | try
30 | {
31 | #pragma warning disable 618
32 | return Assembly.LoadWithPartialName("Microsoft.ResourceManagement");
33 | #pragma warning restore 618
34 | }
35 | catch
36 | {
37 | try
38 | {
39 | return Assembly.Load("Microsoft.ResourceManagement.dll");
40 | }
41 | catch
42 | {
43 | }
44 | }
45 |
46 | }
47 |
48 | return null;
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/src/Lithnet.ResourceManagement.Resolver/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Lithnet.ResourceManagement.Resolver")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Lithnet.ResourceManagement.Resolver")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("fb9c8b6c-aeab-48ce-8aef-dbdc61a959b8")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------