Skip to content

Instantly share code, notes, and snippets.

@JaimeStill
Last active August 10, 2017 20:07
Show Gist options
  • Save JaimeStill/44f49c9a5b8a504f313fb3f09d4a7a6c to your computer and use it in GitHub Desktop.
Save JaimeStill/44f49c9a5b8a504f313fb3f09d4a7a6c to your computer and use it in GitHub Desktop.
Stuff to remember for PowerShell interactions in C# / Angular
.account-card {
padding: 0 0 20px 0;
margin-left: 5%;
margin-right: 5%;
}
.admin-section {
display: flex;
align-content: space-around;
align-items: flex-start;
justify-content: flex-start;
flex-wrap: nowrap;
width: 100%;
box-sizing: border-box'
}
.input-section {
display: flex;
align-content: center;
align-items: center;
justify-content: center;
flex-wrap: nowrap;
width: 100%;
box-sizing: border-box;
}
.action-section button {
margin: 10px 15px;
}
md-input-container.mat-input-container {
width: 30%;
}
<md-card class="account-card">
<md-card-content>
<md-toolbar color="accent" class="mat-elevation-z5">Output Console</md-toolbar>
<console></console>
<section class="action-section">
<button md-button color="primary" (click)="createAccount()">Create Account</button>
<button md-button color="warn" (click)="retryEmail()" *ngIf="emailFailed">Retry Email</button>
<button md-button color="warn" (click)="retrySip()" *ngIf="sipFailed">Retry Sip</button>
</section>
<md-toolbar color="accent" class="mat-elevation-z5">Admin Credentials</md-toolbar>
<section class="admin-section">
<md-input-container>
<input mdInput placeholder="Admin User" [(ngModel)]="account.adminUser" />
</md-input-container>
<md-input-container>
<input mdInput placeholder="Admin Password" [(ngModel)]="account.adminPassword" type="password" />
</md-input-container>
</section>
<md-toolbar color="accent" class="mat-elevation-z5">New Account</md-toolbar>
<section class="input-section">
<md-input-container>
<input mdInput placeholder="Last Name" [(ngModel)]="account.surname" />
</md-input-container>
<md-input-container>
<input mdInput placeholder="First Name" [(ngModel)]="account.givenName" />
</md-input-container>
<md-input-container>
<input mdInput placeholder="Middle" [(ngModel)]="account.initials" maxlength="1" />
</md-input-container>
</section>
<section class="input-section">
<md-input-container>
<input mdInput placeholder="Title" [(ngModel)]="account.title" />
</md-input-container>
<md-input-container>
<input mdInput placeholder="Username" [(ngModel)]="account.samAccountName" maxlength="14" />
</md-input-container>
<md-input-container>
<input mdInput placeholder="Password" [(ngModel)]="account.accountPassword" />
</md-input-container>
</section>
<section class="input-section">
<md-input-container>
<input mdInput placeholder="Office Phone" [(ngModel)]="account.officePhone" type="tel" />
</md-input-container>
<md-input-container>
<input mdInput placeholder="Company" [(ngModel)]="account.company" />
</md-input-container>
<md-input-container>
<input mdInput placeholder="Department" [(ngModel)]="account.department" />
</md-input-container>
</section>
<section class="path-section">
<p>Selected OU: {{account.path}}</p>
</section>
<directory-tree></directory-tree>
</md-card-content>
</md-card>
import { Component } from '@angular/core';
import { AccountService } from '../../services/account.service';
import { Account } from '../../models/account.model';
@Component({
selector: 'account-form',
templateUrl: 'account-form.component.html',
styleUrls: ['account-form.component.css']
})
export class AccountFormComponent {
account: Account = new Account();
emailFailed = false;
sipFailed = false;
constructor(private accountService: AccountService) {
accountService.account.subscribe(account => {
this.account = account;
});
accountService.selectedDirectory.subscribe(path => {
this.account.path = path.rootDN;
});
accountService.emailFailed.subscribe(bool => {
this.emailFailed = bool;
});
accountService.sipFailed.subscribe(bool => {
this.sipFailed = bool;
});
}
createAccount() {
this.accountService.setAccount(this.account);
this.accountService.createAccount();
}
retryEmail() {
this.accountService.setAccount(this.account);
this.accountService.enableMailbox();
}
retrySip() {
this.accountService.setAccount(this.account);
this.accountService.createSipAddress();
}
}
export class Account {
samAccountName: string;
surname: string;
givenName: string;
initials: string;
path: string;
officePath: string;
company: string;
department: string;
title: string;
accountPassword: string;
adminUser: string;
adminPassword: string;
}
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { ToasterService } from './toaster.service';
import { CoreApiService } from './core-api.service';
import { Account } from '../models/account.model';
import { DirectoryTree } from '../models/directory-tree.model';
import { ConsoleOutput } from '../models/console-output.model';
@Injectable()
export class AccountService {
private consoleValues = new Array<ConsoleOutput>();
private directoryTreeSubject = new Subject<DirectoryTree>();
private selectedDirectorySubject = new BehaviorSubject<DirectoryTree>(new DirectoryTree());
private accountSubject = new BehaviorSubject<Account>(new Account());
private consoleSubject = new Subject<Array<ConsoleOutput>>();
private emailFailedSubject = new Subject<boolean>();
private sipFailedSubject = new Subject<boolean>();
directoryTree = this.directoryTreeSubject.asObservable();
selectedDirectory = this.selectedDirectorySubject.asObservable();
account = this.accountSubject.asObservable();
console = this.consoleSubject.asObservable();
emailFailed = this.emailFailedSubject.asObservable();
sipFailed = this.sipFailedSubject.asObservable();
constructor(private http: Http, private toaster: ToasterService, private coreApi: CoreApiService) {}
setAccount(account: Account) {
this.accountSubject.next(account);
}
setSelectedDirectory(directory: DirectoryTree) {
this.selectedDirectorySubject.value.isSelected = false;
directory.isSelected = true;
this.selectedDirectorySubject.next(directory);
}
updateConsole(output: ConsoleOutput) {
this.consoleValues.push(output);
this.consoleSubject.next(this.consoleValues);
}
addConsoleMessage(result: string, hasError: boolean, error?: string) {
const consoleMessage = new ConsoleOutput();
consoleMessage.result = result;
consoleMessage.hasError = hasError;
consoleMessage.error = error;
this.updateConsole(consoleMessage);
}
getDirectoryTree() {
this.http.get('/api/provision/getDirectoryTree')
.map(this.coreApi.extractData)
.catch(this.coreApi.handleError)
.subscribe(tree => {
this.directoryTreeSubject.next(tree);
},
error => {
this.toaster.sendErrorMessage(error);
});
}
createAccount() {
this.addConsoleMessage(`Creating account for ${this.accoutnSubject.value.samAccountName}`, false);
const body = JSON.stringify(this.accountSubject.value);
return this.http.post('/api/provision/createAccount', body, this.coreApi.getRequestOptions())
.map(this.coreApi.extractData)
.catch(this.coreApi.handleError)
.subscribe((res: ConsoleOutput) => {
this.updateConsole(res);
if (res.hasError) {
this.toaster.sendErrorMessage(res.error);
} else {
this.enableMailbox();
}
},
error => {
this.addConsoleMessage(undefined, true, error);
this.toaster.sendErrorMessage(error);
});
}
enableMailbox() {
this.addConsoleMessage(`Enabling mailbox for ${this.accountSubject.value.samAccountName}`, false);
const body = JSON.stringify(this.accountSubject.value);
return this.http.post('/api/provision/enableMailbox', body, this.coreApi.getRequestOptions())
.map(this.coreApi.extractData)
.catch(this.coreApi.handleError)
.subscribe((res: ConsoleOutput) => {
this.updateConsole(res);
if (res.hasError) {
this.toaster.sendErrorMessage(res.error);
this.emailFailedSubject.next(true);
} else {
this.emailFailedSubject.next(false);
this.createSipAddress();
}
},
error => {
this.emailFailedSubject.next(true);
this.addConsoleMessage(undefined, true, error);
this.toaster.sendErrorMessage(error);
});
}
createSipAddress() {
this.addConsoleMessage(`Creating sipAddress for ${this.accountSubject.value.samAccountName}`, false);
const body = JSON.stringify(this.accountSubject.value);
return this.http.post('/api/provision/createSipAddress', body, this.coreApi.getRequestOptions())
.map(this.coreApi.extractData)
.catch(this.coreApi.handleError)
.subscribe((res: ConsoleOutput) => {
this.updateConsole(res);
if (res.hasError) {
this.toaster.sendErrorMessage(res.error);
this.sipFailedSubject.next(true);
} else {
this.sipFailedSubject.next(false);
this.toaster.sendSuccessMessage(`${this.accountSubject.value.samAccountName} successfully provisioned`);
this.accountSubject.next(new Account());
}
},
error => {
this.sipFailedSubject.next(true);
this.addConsoleMessage(undefined, true, error);
this.toaster.sendErrorMessage(error);
});
}
}
public class AccountModel
{
public string samAccountName { get; set; }
public string surname { get; set; }
public string givenName { get; set; }
public string initials { get; set; }
public string path { get; set; }
public string officePhone { get; set; }
public string company { get; set; }
public string department { get; set; }
public string title { get; set; }
public string accountPassword { get; set; }
public string adminUser { get; set; }
public string adminPassword { get; set; }
}
import { NgModule } from '@angular/core';
import {
FullscreenOverlayContainer,
MdAutocompleteModule,
MdButtonModule,
MdButtonToggleModule,
MdCardModule,
MdCheckboxModule,
MdChipsModule,
MdCoreModule,
MdDatepickerModule,
MdDialogModule,
MdGridListModule,
MdIconModule,
MdInputModule,
MdListModule,
MdMenuModule,
MdNativeDateModule,
MdProgressBarModule,
MdProgressSpinnerModule,
MdRadioModule,
MdRippleModule,
MdSelectModule,
MdSidenavModule,
MdSliderModule,
MdSlideToggleModule,
MdSnackBarModule,
MdTabsModule,
MdToolbarModule,
MdTooltipModule,
OverlayContainer,
MdTableModule,
MdPaginatorModule,
MdSortModule
} from '@angular/material';
import {
CdkTableModule
} from '@angular/cdk';
@NgModule({
exports: [
MdAutocompleteModule,
MdButtonModule,
MdButtonToggleModule,
MdCardModule,
MdCheckboxModule,
MdChipsModule,
MdCoreModule,
MdDatepickerModule,
MdDialogModule,
MdGridListModule,
MdIconModule,
MdInputModule,
MdListModule,
MdMenuModule,
MdNativeDateModule,
MdProgressBarModule,
MdProgressSpinnerModule,
MdRadioModule,
MdRippleModule,
MdSelectModule,
MdSidenavModule,
MdSliderModule,
MdSlideToggleModule,
MdSnackBarModule,
MdTabsModule,
MdToolbarModule,
MdTooltipModule,
MdTableModule,
MdPagniatorModule,
MdSortModule,
CdkTableModule
]
})
export class AppMaterialModule { }
import { NgModule } from '@angular/core';
import { RequestOptions } from '@angular/http';
import { RouterModule } from '@angular/router';
import { AppMaterialModule } from './app.module.material';
import { ToasterService } from './services/toaster.service';
import { CoreApiService } from './services/core-api.service';
import { AccountService } from './services/account.service';
import { NoCacheRequestOptions } from './services/no-cache-request-options';
import { AppComponent } from './components/app/app.component';
import { HomeComponent } from './components/home/home.component';
import { DirectoryTreeComponent } from './components/directory-tree/directory-tree.component';
import { DirectoryComponent } from './components/directory/directory.component';
import { AccountFormComponent } from './components/account/account-form.component';
import { ConsoleComponent } form './components/console/console.component';
export const sharedConfig: NgModule = {
bootstrap: [ AppComponent ],
declarations: [
AppComponent,
HomeComponent,
DirectoryTreeComponent,
DirectoryComponent,
AccountFormComponent,
ConsoleComponent
],
providers: [
ToasterService,
CoreApiService,
AccountService,
{ provide: RequestOptions, useClass: NoCacheRequestOptions }
],
imports: [
AppMaterialModule,
RouterModule.forRoot([
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: '**', redirectTo: 'home' }
])
]
};
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { sharedConfig } from './app.module.shared';
@NgModule({
bootstrap: sharedConfig.bootstrap,
declarations: sharedConfig.declarations,
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
HttpModule,
...sharedConfig.imports
],
providers: [
{ provide: 'ORIGIN_URL', useValue: location.origin },
...sharedConfig.providers
]
})
export class AppModule { }
export class ConsoleOutput {
hasError: boolean;
result: string;
error: string;
}
.console {
font-family: 'Consolas', Courier New, Courier, monospace;
background: #333;
margin: 10px;
padding: 10px;
overflow: auto;
height: 90px;
border-radius: 2px;
}
<section class="console">
<p *ngFor="let stream of output" [style.color]="stream.hasError ? 'red' : 'limegreen'">{{stream.hasError ? stream.error : stream.result}}</p>
</section>
import { Component } from '@angular/core';
import { AccountService } from '../../services/account.service';
import { ConsoleOutput } from '../../models/console-output.model';
@Component({
selector: 'console',
templateUrl: 'console.component.html',
styleUrls: ['console.component.css']
})
export class ConsoleComponent {
output: Array<ConsoleOutput> = new Array<ConsoleOutput>();
constructor(private accountService: AccountService) {
accountService.console.subscribe(output => {
this.output = output;
});
}
}
public class ConsoleOutput
{
public bool hasError { get; set; }
public string result { get; set; }
public string error { get; set; }
}
import { Injectable } from '@angular/core';
import { Response, RequestOptions, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
@Injectable()
export class CoreApiService {
extractData(res: Response) {
return res.json() || {};
}
handleError(error: Response | any) {
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || body.Message || JSON.stringify(body);
errMsgt = `${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
getRequestOptions(): RequestOptions {
const headers = new Headers({
'Content-Type': 'application/json'
});
return new RequestOptions({ headers: headers });
}
}
[CmdletBinding()]
Param(
[Parameter()]
[string]$samAccountName,
[Parameter()]
[string]$surname,
[Parameter()]
[string]$givenName,
[Parameter()]
[string]$initials,
[Parameter()]
[string]$path,
[Parameter()]
[string]$officePhone,
[Parameter()]
[string]$company,
[Parameter()]
[string]$department,
[Parameter()]
[string]$title,
[Parameter()]
[string]$accountPassword,
[Parameter()]
[PSCredential]$credential
)
$name = "$surname, $givenName $title"
$userPrincipalName = "$samAccountName@domain.com"
Write-Host "Initializing Active Directory Session..." -ForegroundColor DarkGreen
$session = New-PSSession -ComputerName {server} -Credential $credential
Invoke-Command -Session $session -ScriptBlock { Import-Module ActiveDirectory }
Import-PSSession -Session $session -Module ActiveDirectory -AllowClobber
Write-Host "Creating Active Directory Account for $samAccountName" -ForegroundColor DarkGreen
New-ADUser -Name $name -DisplayName $name -EmailAddress $userPrincipalName -SamAccountName $samAccountName -Surname $surname -GivenName $givenName -Initials $initials -Path $path -OfficePhone $officePhone -Department $department -Company $company -Title $title -AccountPassword (ConvertTo-SecureString $accountPassword -AsPlainText -Force) -ChangePasswordAtLogon 1 -Enabled 1
Write-Host "Closing Active Directory Extension..." -ForegroundColor DarkGreen
Remove-PSSession $session
[CmdletBinding()]
Param(
[Parameter()]
[string]$username,
[Parameter()]
[PSCredential]$credential
)
Write-Host "Initializing Lync Session..." -ForegroundColor DarkGreen
$options = New-PSSessionOptions -ProxyAccessType NoProxyServer
$session = New-PSSession -ConnectionUri "https://{server}/ocspowershell" -Credential $credential -AllowRedirection -SessionOption $options
Import-PSSession $session
Write-Host "Setting SIP Address for $username" -ForegroundColor DarkGreen
Enable-CsUser -Identity "$username@domain.com" -RegistrarPool "{server}" -SipAddressType UserPrincipalName
Start-Sleep -s 10
Write-Host "Verifying Lync Configuration" -ForegroundColor DarkGreen
Get-CsUser -Identity "$username@domain.com" | Select-Object -property UserPrincipalName, ProxyAddresses
Write-Host "Closing Lync Session...." -ForegroundColor DarkGreen
Remove-PSSession $session
<md-progress-bar mode="indeterminate" color="accent" *ngIf="!directory"></md-progress-bar>
<section *ngIf="directory" class="directory-container">
<h3>Organizational Units</h3>
<directory [directory]="directory"></directory>
</section>
import { Component } from '@angular/core';
import { AccountService } from '../../services/account.service';
import { DirectoryTree } from '../../models/directory-tree.model';
@Component({
selector: 'directory-tree',
templateUrl: 'directory-tree.component.html'
})
export class DirectoryTreeComponent {
directory: DirectoryTree;
constructor(private accountService: AccountService) {
accountService.directoryTree.subscribe(tree => {
this.directory = tree;
});
accountService.getDirectoryTree();
}
}
export class DirectoryTree {
rootDN: string;
rootName: string;
childOUs: Array<DirectoryTree>;
isExpanded: boolean;
isSelected: boolean;
depth: number;
constructor() {
this.isExpanded = false;
this.isSelected = false;
this.depth = 0;
this.childOUs = new Array<DirectoryTree>();
}
}
.ou-card {
display: flex;
align-content: space-around;
align-items: center;
justify-content: flex-start;
padding: 4px;
background-color: #444;
border-radius: 2px;
margin-bottom: 6px;
width: 25%;
min-width: 220px;
}
.ou-card p {
flex: 1 1 auto;
}
.ou-card md-slide-toggle.mat-slide-toggle {
margin-top: 8px;
}
<section [style.margin-left.px]="(directory.depth * 32) + 15" class="ou-card mat-elevation-z5">
<button md-icon-button (click)="toggleDirectoryExpand()">
<md-icon *ngIf="directory.isExpanded && directory.childOUs.length > 0">expand_more</md-icon>
<md-icon *ngIf="!directory.isExpanded && directory.childOUs.length > 0">chevron_right</md-icon>
<md-icon *ngIf="directory.childOUs.length < 1">last_page</md-icon>
</button>
<p>{{directory.rootName}}</p>
<md-slide-toggle color="accent" [checked]="directory.isSelected" (change)="setSelectedDirectory()"></md-slide-toggle>
</section>
<div *ngIf="directory.childOUs.length > 0 && directory.isExpanded">
<directory *ngFor="let directory of directory.childOUs; trackBy: trackDirectories" [directory]="directory"></directory>
</div>
import { Component, Input } from '@angular/core';
import { AccountService } from '../../services/account.service';
import { DirectoryTree } from '../../models/directory-tree.model';
@Component({
selector: 'directory',
templateUrl: 'directory.component.html'
styleUrls: ['directory.component.css']
})
export class DirectoryComponent {
@Input() directory: DirectoryTree;
constructor(private accountService: AccountService) {}
toggleDirectoryExpand() {
this.directory.isExpanded = !this.directory.isExpanded;
}
setSelectedDirectory() {
if (!this.directory.isSelected) {
this.accountService.setSelectedDirectory(this.directory);
} else {
this.directory.isSelected = false;
this.accountService.setSelectedDirectory(new DirectoryTree());
}
}
trackDirectories(index: number, item: DirectoryTree) {
if (!item) return null;
return item.rootDN;
}
}
public class DirectoryTree
{
DirectoryEntry rootOU;
public DirectoryEntry RootOU
{
get { return rootOU; }
set
{
rootOU = value;
RootDN = RootOU.Path;
RootName = RootOU.Name.Remove(0, 3);
}
}
public string RootDN { get; set; }
public string RootName { get; set; }
public List<DirectoryTree> ChildOUs { get; set; }
public int Depth { get; set; }
}
[CmdletBinding()]
Param(
[Parameter()]
[string]$username,
[Parameter()]
[PSCredential]$credential
)
Write-Host "Initializing Exchange Session..." -ForegroundColor DarkGreen
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://{server}/powershell" -Credential $credential -Authentication Kerberos -AllowRedirection
Import-PSSession $session
Write-Host "Enabling Mailbox for $username" -ForegroundColor DarkGreen
Enable-Mailbox -Identity "DOMAIN\$username" -Database {DB}
Write-Host "SEtting Archive for $username" -ForegroundColor DarkGreen
Enable-Mailbox -Identity "DOMAIN\$username" -Archive -ArchiveDatabase {ArchiveDB}
Write-Host "Setting Retention Policy for $username" -ForegroundColor DarkGreen
Set-Mailbox "$username@domain.com" -RetentionPolicy {RetentionPolicy}
Write-Host "Closing Exchange Session..." -ForegroundColor DarkGreen
Remove-PSSession $session
import 'reflect-metadata';
import 'zone.js';
import 'hammerjs';
import './polyfills';
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
if (module['hot']) {
module['hot'].accept();
module['hot'].dispose(() => {
const oldRootElem = document.querySelector('app');
const newRootElem = document.createElement('app');
oldRootElem.parentNode.insertBefore(newRootElem, oldRootElem);
modulePromise.then(appModule => appModule.destroy());
});
} else {
enableProdMode();
}
const modulePromise = platformBrowserDynamic().bootstrapModule(AppModule);
import { Injectable } from '@angular/core';
import { BaseRequestOptions, Headers } from '@angular/http';
@Injectable()
export class NoCacheRequestOptions extends BaseRequestOptions {
headers = new Headers({
'Cache-Control': 'no-cache',
'Pragma': 'no-cache',
'Expires': 'Sat, 01 Jan 2000 00:00:00 GMT'
});
}
[Route("api/[controller]")]
public class ProvisionController : Controller
{
public const string RootDN = @"{rootDN}"
[HttpGet("[action]")]
public async Task<DirectoryTree> GetDirectoryTree()
{
return await RootDN.InitializeDirectoryTree();
}
[HttpPost("[action]")]
public async Task<ConsoleOutput> CreateAccount([FromBody]AccountModel model)
{
return await model.CreateAccount();
}
[HttpPost("[action]")]
public async Task<ConsoleOutput> EnableMailbox([FromBody]AccountModel model)
{
return await model.EnableMailbox();
}
[HttpPost("[action]")]
public async Task<ConsoleOutput> CreateSipAddress([FromBody]AccountModel model)
{
return await model.CreateSipAddress();
}
}
import { Injectable } from '@angular/core';
import { MdSnackBar, MdSnackBarConfig } from '@angular/material';
@Injectable()
export class ToasterService {
private config: MdSnackBarConfig = new MdSnackBarConfig();
private message = 'Hello from Toaster Service';
constructor(private snackbar: MdSnackBar) {
this.config.duration = 5000;
this.config.extraClasses = new Array<string>();
}
sendMessage() {
this.snackbar.open(this.message, 'Close', this.config);
}
setMessage(message: string) {
this.message = message;
}
setDuration(duration: number) {
this.config.duration = duration;
}
setClasses(classes: string[]) {
this.config.extraClasses = classes;
}
sendColorMessage(message: string, colors: string[]) {
this.setMessage(message);
this.setClasses(colors);
this.sendMessage();
}
sendErrorMessage(message: string) {
this.setMessage(message);
this.setClasses(['toaster-warn']);
this.sendMessage();
}
sendWarningMessage(message: string) {
this.setMessage(message);
this.setClasses(['toaster-orange']);
this.sendMessage();
}
sendSuccessMessage(message: string) {
this.setMessage(message);
this.setClasses(['toaster-green']);
this.sendMessage();
}
}
public static class UtilityExtensions
{
public static string GetExceptionMessageChain(this Exception ex)
{
var message = new StringBuilder(ex.Message);
if (ex.InnerException != null)
{
message.AppendLine(GetExceptionMessageChain(ex.InnerException));
}
return message.ToString();
}
public static async Task<string> GetTextFromEmbeddedResource(this string resourceName)
{
string text = string.Empty;
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
{
using (StreamReader reader = new StreamReader(stream))
{
text = await reader.ReadToEndAsync();
}
}
return text;
}
public static Task<ConsoleOutput> GetPowerShellOutput(this PowerShell ps)
{
return Task.Run(() =>
{
var result = new StringBuilder();
var error = new StringBuilder();
var output = new ConsoleOutput();
output.hasError = ps.HadErrors;
if (ps.Streams.Error.Count > 0)
{
foreach (var err in ps.Streams.Error)
{
error.AppendLine(err.GetCategoryInfo());
error.AppendLine(err.Exception.GetExceptionMessageChain());
}
}
if (ps.Streams.Information.Count > 0)
{
foreach (var info in ps.Streams.Information)
{
result.AppendLine(info.ToString());
}
}
output.result = result.ToString();
output.error = error.ToString();
return output;.
});
}
public static string GetCategoryInfo(this ErrorRecord error)
{
var output = new StringBuilder();
output.AppendLine($"Activity: {error.CategoryInfo.Activity}");
output.AppendLine($"Category: {error.CategoryInfo.Category.ToString()}");
output.AppendLine($"Reason: {error.CategoryInfo.Reason}");
output.AppendLine($"TargetName: {error.CategoryInfo.TargetName}");
return output.ToString();
}
public static async Task<DirectoryTree> InitializeDirectoryTree(this string distinguishedName)
{
var tree = new DirectoryTree
{
RootOU = new DirectoryEntry(distinguishedName),
Depth = 0
};
await tree.BuildDirectoryTree();
return tree;
}
public static async Task BuildDirectoryTree(this DirectoryTree directory)
{
foreach (var child in directory.RootOU.Children.Cas<DirectoryEntry>()
.Where(x => x.SchemaClassName.Equals("organizationalUnit"))
.AsEnumerable())
{
DirectoryTree childTree = new DirectoryTree
{
RootOU = child,
Depth = directory.Depth + 1
};
await childTree.BuildDirectoryTree();
directory.ChildOUs.Add(childTree);
}
directory.ChildOUs = directory.ChildOUs.OrderBy(x => x.RootName).ToList();
}
public static PSCredentail CreateCredential(this AccountModel model)
{
var password = new SecureString();
foreach (var c in model.adminPassword)
{
password.AppendChar(c);
}
var credential = new PSCredential(model.adminUser, password);
return credential;
}
public static async Task<ConsoleOutput> CreateAccount(this AccountModel model)
{
try
{
InitialSessionState iss = InitialSessionState.CreateDefault();
iss.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Unrestricted;
using (Runspace rs = RunspaceFactory.CreateRunspace(iss))
{
rs.Open();
var script = await ("Scripts.Create-Account.ps1").GetTextFromEmbeddedResource();
Command createAccount = new Command(script, true);
createAccount.Parameters.Add("samAccountName", model.samAccountName);
createAccount.Parameters.Add("surname", model.surname);
createAccount.Parameters.Add("givenName", model.givenName);
createAccount.Parameters.Add("initials", model.initials);
createAccount.Parameters.Add("path", model.path.Remove(0, 7));
createAccount.Parameters.Add("officePhone", model.officePhone);
createAccount.Parameters.Add("company", model.company);
createAccount.Parameters.Add("department", model.department);
createAccount.Parameters.Add("title", model.title);
createAccount.Parameters.Add("accountPassword", model.accountPassword);
createAccount.Parameters.Add("credential", model.CreateCredential());
using (PowerShell ps = PowerShell.Create())
{
ps.Runspace = rs;
ps.Commands.AddCommand(createAccount);
ps.Invoke();
return await ps.GetPowerShellOutput();
}
}
}
catch (Exception ex)
{
throw new Exception(ex.GetExceptionMessageChain());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment