Last active
August 10, 2017 20:07
-
-
Save JaimeStill/44f49c9a5b8a504f313fb3f09d4a7a6c to your computer and use it in GitHub Desktop.
Stuff to remember for PowerShell interactions in C# / Angular
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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%; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class ConsoleOutput { | |
hasError: boolean; | |
result: string; | |
error: string; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.console { | |
font-family: 'Consolas', Courier New, Courier, monospace; | |
background: #333; | |
margin: 10px; | |
padding: 10px; | |
overflow: auto; | |
height: 90px; | |
border-radius: 2px; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<section class="console"> | |
<p *ngFor="let stream of output" [style.color]="stream.hasError ? 'red' : 'limegreen'">{{stream.hasError ? stream.error : stream.result}}</p> | |
</section> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ConsoleOutput | |
{ | |
public bool hasError { get; set; } | |
public string result { get; set; } | |
public string error { get; set; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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