Install PowerShell Options

The best powershell script that I should find in this learning path, was it that enabled my PowerShell with the capabilities to connect to Office 365, AzureAD, SkypeFBO, and Exchange Online.

this was found in the TechNet, but I’ve found it so interesting that I would like to share it. after you ran this, a menu will show, after that the modules can be installed simply selecting a number.

Go ahead. and try it

<#
.SYNOPSIS
Installs all required Powershell Modules, prompts user for needed info to connect to the different on premises and cloud services.
.DESCRIPTION
Allows easy user installation of powershell tools and connection strings.
.NOTES
Version       : 1.3 – Set IgnoreCA/CRL on Lync and Exchange Remote sessions to improve issues with non domain joined/VPN sessions (Thanks to Martin Bauer)
– Fixed the $prereq flag to clear once s/w installed correctly (weird connect to azure prerequisites menu prompt)
– Added S4B Online Powershell.  S4B On premises code is already compatible, just a menu update there (no new download yet!)
– Added Sharepoint Online Shell new revision 16.0.4017.1200 (http://www.microsoft.com/en-us/download/details.aspx?id=35588)
: 1.2 – Added 2 new options to set credentials per session globally for on premises and office 365
:     – Added Azure IaaS PowerShell to module list
:     – Added improved menu logic and menu reloads after every option
– Added logic for version checking on modules – will complete whenever updates occur
: 1.1 – Fixed the LyncOnlineConnector import line, added URL of blog article to this section.
: 1.0 – addressed MS Online Services Requirement for Azure AD on Windows 8.0, added more logging
Version history                   : .91 Fixed Lync Online installer to be quiet.
: .90 First version!
  Rights Required   : Administrative rights on any services
: Local Admin on machine to install software – elevated powershell is recommended, but
most installs prompt for elevation
Sched Task Required : No
Author/Copyright  : Chris Lehr – Multiple Modules borrowed from Pat Richard
Blog                  : http://blog.chrislehr.com/2015/04/install-powershelloptionsps1-script-to.html
Disclaimer       : You running this script means you won’t blame me if this breaks your stuff. This script is
provided AS IS without warranty of any kind. I disclaim all implied warranties including,
without limitation, any implied warranties of merchantability or of fitness for a particular
purpose. The entire risk arising out of the use or performance of the sample scripts and
documentation remains with you. In no event shall I be liable for any damages whatsoever
(including, without limitation, damages for loss of business profits, business interruption,
loss of business information, or other pecuniary loss) arising out of the use of or inability

Assumptions     : ExecutionPolicy of AllSigned (recommended), RemoteSigned or Unrestricted (not recommended)
Limitations     : Only works on Windows 8/8.1 and Windows Server 2012 and Windows Server 2012 R2. This is by design. There are no
plans to support Windows Server 2008 R2.
Known issues    : Downloading files through a proxy is still somewhat of a kludge, especially if the proxy isn’t configured in IE.

.LINK
none yet
.EXAMPLE
.\Install-PowerShellOptions.ps1
  Description
———–
Runs script with default values.
#>
param(
# Defines the location for any downloaded files. Defaults to “c:\_install”. Additionally, log files generated by this script are located in a subfolder of TargetFolder called “logs”. TargetFolder does not support paths with spaces, but does support non-hidden UNC paths.
[Parameter(ValueFromPipeline = $False, ValueFromPipelineByPropertyName = $True, ParameterSetName = “Default”)]
[ValidatePattern(‘(?:[a-zA-Z]\:|\\\\[]\w\.+|\w-\\[\w.]+)\\(?:[\w]+\\)*\w[\w.]+’)]
[string] $TargetFolder = “$env:SystemDrive\_Install”
) # end of param block
function Write-Log {
<#
.SYNOPSIS
Extensive function to write data to either the console screen, a log file, and/or a Windows event log.
 .DESCRIPTION
Extensive function to write data to either the console screen, a log file, and/or a Windows event log. Data can be written as info, warning, error, and includes indentation, time stamps, etc.
 .NOTES
Version       : 2.7
Wish list      : Better error trapping
Rights Required   : Local administrator on server
Sched Task Required : No
Lync Server Version : N/A
Author/Copyright  :
Email/Blog/Twitter : pat@innervation.com  http://www.ehloworld.com @patrichard
Dedicated Post   :
Disclaimer       : You running this script means you won’t blame me if this breaks your stuff. This script is
provided AS IS without warranty of any kind. I disclaim all implied warranties including,
without limitation, any implied warranties of merchantability or of fitness for a particular
purpose. The entire risk arising out of the use or performance of the sample scripts and
documentation remains with you. In no event shall I be liable for any damages whatsoever
(including, without limitation, damages for loss of business profits, business interruption,
loss of business information, or other pecuniary loss) arising out of the use of or inability
to use the script or documentation.
Acknowledgements   : Test for log names and sources
http://powershell.com/cs/blogs/tips/archive/2013/06/10/testing-event-log-names-and-sources.aspx
Assumptions     : ExecutionPolicy of AllSigned (recommended), RemoteSigned or Unrestricted (not recommended)
Limitations     :
Known issues    :
 .LINK
.EXAMPLE
.\
   Description
———–
.INPUTS
None. You cannot pipe objects to this script.
#>
[CmdletBinding(SupportsShouldProcess = $True, SupportsPaging = $True)]
param(
# The type of message to be logged. Alias is ‘type’.
[Parameter(Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[ValidateSet(“Error”, “Warn”, “Info”)]
[ValidateNotNullOrEmpty()]
[string] $level = “Info”,
  # The message to be logged.
[Parameter(Position = 1, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Mandatory = $true, HelpMessage = “No message specified.”)]
[ValidateNotNullOrEmpty()]
[string] $Message,
  # Specifies that $message should not the sent to the log file.
[Parameter(Position = 2, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[switch] $NoLog,
  # Specifies to not display the message to the console.
[Parameter(Position = 3, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[switch] $NoConsole,
  # The number of spaces to indent the message in the log file.
[Parameter(Position = 4, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[ValidateRange(1,30)]
[ValidateNotNullOrEmpty()]
[Int16] $Indent = 0,
  # Specifies what color the text should be be displayed on the console. Ignored when switch ‘NoConsoleOut’ is specified.
[Parameter(Position = 5, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[ValidateSet(“Black”, “DarkMagenta”, “DarkRed”, “DarkBlue”, “DarkGreen”, “DarkCyan”, “DarkYellow”, “Red”, “Blue”, “Green”, “Cyan”, “Magenta”, “Yellow”, “DarkGray”, “Gray”, “White”)]
[ValidateNotNullOrEmpty()]
[String] $ConsoleForeground = ‘White’,
  # Existing log file is deleted when this is specified. Alias is ‘Overwrite’.
[Parameter(Position = 6, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[Switch] $Clobber,
  # The name of the system event log, e.g. ‘Application’. Note that writing to the system event log requires elevated permissions.
[Parameter(Position = 7, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[ValidateSet(“Application”,”System”,”Security”,”Lync Server”,”Microsoft Office Web Apps”)]
[ValidateNotNullOrEmpty()]
[String] $EventLogName = “Application”,
  # The name to appear as the source attribute for the system event log entry. This is ignored unless ‘EventLogName’ is specified.
[Parameter(Position = 8, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[ValidateNotNullOrEmpty()]
[String] $EventSource = $($MyInvocation.ScriptName).Name,
  # The ID to appear as the event ID attribute for the system event log entry. This is ignored unless ‘EventLogName’ is specified.
[Parameter(Position = 9, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[ValidateRange(1,65535)]
[ValidateNotNullOrEmpty()]
[Int32] $EventID = 1,
  # The text encoding for the log file. Default is ASCII.
[Parameter(Position = 10, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[ValidateSet(“Unicode”,”Byte”,”BigEndianUnicode”,”UTF8″,”UTF7″,”UTF32″,”ASCII”,”Default”,”OEM”)]
[ValidateNotNullOrEmpty()]
[String] $LogEncoding = “ASCII”
)
try {
[string]$LogFolder = Split-Path $LogPath -Parent
if (-not(Test-Path $LogFolder)){New-Item $LogFolder -type Directory | Out-Null}
$msg = “{0} : {1} : {2}{3}” -f (Get-Date -Format “yyyy-MM-dd HH:mm:ss”), $Level.ToUpper(), (”  ” * $Indent), $Message
if (-not($NoConsole)){
switch ($level) {
“Error” {$Host.UI.WriteErrorLine(“$Message”)}
“Warn” {Write-Warning $Message}
“Info” {Write-Host $Message -ForegroundColor $ConsoleForeground}
}
}
if (-not($NoLog)){
if ($Clobber) {
$msg | Out-File -FilePath $LogPath -Encoding $LogEncoding -Force
} else {
$msg | Out-File -FilePath $LogPath -Encoding $LogEncoding -Append
}
}
  if ($EventLogName) {
if (-not $EventSource) {
[string] $EventSource = $([IO.FileInfo] $MyInvocation.ScriptName).Name
}
   if(-not [Diagnostics.EventLog]::SourceExists($EventSource)) {
[Diagnostics.EventLog]::CreateEventSource($EventSource, $EventLogName)
}
   switch ($Level) {
“Error” {$EntryType = “Error”}
“Warn”  {$EntryType = “Warning”}
“Info”  {$EntryType = “Information”}
Default  {$EntryType = “Information”}
}
Write-EventLog -LogName $EventLogName -Source $EventSource -EventId 1 -EntryType $EntryType -Message $Message
}
$msg = “”
}
catch {
Throw “Failed to create log entry in: ‘$LogPath’. The error was: ‘$_’.”
}
} # end function Write-Log
function Set-ModuleStatus {
<#
.SYNOPSIS
Imports a specified PowerShell module, with error checking.
 .DESCRIPTION
Imports a specified PowerShell module, with error checking.
 .NOTES
Version       : 1.5
Wish list      : Better error trapping
Rights Required   : None
Sched Task Required : No
Lync Server Version : N/A
Author/Copyright  : © Pat Richard, Lync MVP – All Rights Reserved
Email/Blog/Twitter : pat@innervation.com  http://www.ehloworld.com @patrichard
Dedicated Post   :
Disclaimer       : You running this script means you won’t blame me if this breaks your stuff. This script is
provided AS IS without warranty of any kind. I disclaim all implied warranties including,
without limitation, any implied warranties of merchantability or of fitness for a particular
purpose. The entire risk arising out of the use or performance of the sample scripts and
documentation remains with you. In no event shall I be liable for any damages whatsoever
(including, without limitation, damages for loss of business profits, business interruption,
loss of business information, or other pecuniary loss) arising out of the use of or inability
to use the script or documentation.
Acknowledgements   :
Assumptions     : ExecutionPolicy of AllSigned (recommended), RemoteSigned or Unrestricted (not recommended)
Limitations     :
Known issues    :
 .LINK
.EXAMPLE
.\
   Description
———–
.INPUTS
None. You cannot pipe objects to this script.
#>
[CmdletBinding(SupportsShouldProcess = $True, SupportsPaging = $True)]
param (
[parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Mandatory = $true, HelpMessage = “No module name specified!”)]
[ValidateNotNullOrEmpty()]
[string] $name
)
PROCESS{
# Executes once for each pipeline object
# the $_ variable represents the current input object
if (-not(Get-Module -name “$name”)) {
if (Get-Module -ListAvailable | Where-Object Name -eq “$name”) {
Import-Module -Name “$name”
# module was imported
# return $true
} else {
# module was not available
# return $false
}
} else {
# Write-Output “$_ module already imported”
# return $true
}
} # end PROCESS
} # end function Set-ModuleStatus
function Test-IsProxyEnabled {
<#
.SYNOPSIS
Determines (the best it can) if a proxy is in place for Internet access.
 .DESCRIPTION
Determines (the best it can) if a proxy is in place for Internet access. If so, other functions that download files can better handle downloads.
 .NOTES
Version       : 1.1
Wish list      : Better error trapping
Rights Required   : Local administrator on server
Sched Task Required : No
Lync Server Version : N/A
Author/Copyright  : © Pat Richard, Lync MVP – All Rights Reserved
Email/Blog/Twitter : pat@innervation.com  http://www.ehloworld.com @patrichard
Dedicated Post   :
Disclaimer       : You running this script means you won’t blame me if this breaks your stuff. This script is
provided AS IS without warranty of any kind. I disclaim all implied warranties including,
without limitation, any implied warranties of merchantability or of fitness for a particular
purpose. The entire risk arising out of the use or performance of the sample scripts and
documentation remains with you. In no event shall I be liable for any damages whatsoever
(including, without limitation, damages for loss of business profits, business interruption,
loss of business information, or other pecuniary loss) arising out of the use of or inability
to use the script or documentation.
Acknowledgements   :
Assumptions     : ExecutionPolicy of AllSigned (recommended), RemoteSigned or Unrestricted (not recommended)
Limitations     :
Known issues    :
 .LINK
.EXAMPLE
.\
   Description
———–
.INPUTS
None. You cannot pipe objects to this script.
#>
[CmdletBinding(SupportsShouldProcess = $True, SupportsPaging = $True)]
param ()
Write-Log -Message “Checking if a proxy is enabled” -NoConsole -Indent 1
# If this registry key doesn’t exist at all, it’s because IE has never been launched. We need to create it here so that download attempts and proxy checks don’t throw a silent error
if ((Get-Item “HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings”).Property -notcontains “ProxyEnable”){
Write-Log -Message “Internet Explorer has never been opened. Proxy registry values have yet to be set. Setting it to 0 now.” -NoConsole -Indent 1
New-ItemProperty “HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings” -Name ProxyEnable -Value 0 | Out-Null
}
if ((Get-ItemProperty “HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings” -name ProxyEnable -ErrorAction SilentlyContinue).ProxyEnable -ne 0){
Write-Log -Message “A proxy is required” -NoConsole -Indent 2
[string]$ProxyServer = (Get-ItemProperty “HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings” -name ProxyServer).ProxyServer
Write-Log -Message “Configured proxy: `”$ProxyServer`”” -NoConsole -Indent 2
  if (-not($PSDefaultParameterValues.ContainsKey(“Start-BitsTransfer:ProxyAuthentication”))){
Write-Log -Message “Prompting for credentials” -NoConsole -Indent 2
$ProxyCredentials = Get-Credential -Message “Enter Proxy authentication credentials for $ProxyServer” -UserName “${env:USERDOMAIN}\${env:UserName}”
if ($ProxyCredentials){
Write-Log -Message “Credentials entered” -NoConsole -Indent 2
Write-Log -Message “Adding default values for Start-BitsTransfer” -NoConsole -Indent 2
Write-Log -Message “Adding default value for ProxyAuthentication – `”Basic`”” -NoConsole -Indent 2
$PSDefaultParameterValues.Add(“Start-BitsTransfer:ProxyAuthentication”,”Basic”)
$ProxyUserName = $ProxyCredentials.username
Write-Log -Message “Adding default value for ProxyCredential – `”$ProxyUserName`”” -NoConsole -Indent 2
$PSDefaultParameterValues.Add(“Start-BitsTransfer:ProxyCredential”,$ProxyCredentials)
# Write-Log -Message “Adding default value for ProxyList – `”$ProxyServer`”” -NoConsole -Indent 1
# $PSDefaultParameterValues.Add(“Start-BitsTransfer:ProxyList”,$ProxyServer)
# Write-Log -Message “Adding default value for ProxyUsage – `”AutoDetect`”” -NoConsole -Indent 1
# $PSDefaultParameterValues.Add(“Start-BitsTransfer:ProxyUsage”,”AutoDetect”)
} else {
Write-Log -Level error -message “Credentials NOT entered. Following commands will likely fail” -NoConsole -Indent 2
}
}
} else {
Write-Log -Message “Proxy is not enabled” -NoConsole -Indent 2
# Clear the error queue in case the proxy registry key didn’t exist at all and threw an error.
$error.clear()
}
} # end function Test-IsProxyEnabled
function New-FileDownload {
<#
.SYNOPSIS
Downloads a file from a specified URL.
 .DESCRIPTION
Downloads a file from a specified URL. First, it verifies the file does not exist locally. Then ensures Internet access is available, then downloads the file.
 .NOTES
Version       : 1.3
Wish list      : Better error trapping
Rights Required   : Local administrator on server
Sched Task Required : No
Lync Server Version : N/A
Author/Copyright  : © Pat Richard, Lync MVP – All Rights Reserved
Email/Blog/Twitter : pat@innervation.com  http://www.ehloworld.com @patrichard
Dedicated Post   :
Disclaimer       : You running this script means you won’t blame me if this breaks your stuff. This script is
provided AS IS without warranty of any kind. I disclaim all implied warranties including,
without limitation, any implied warranties of merchantability or of fitness for a particular
purpose. The entire risk arising out of the use or performance of the sample scripts and
documentation remains with you. In no event shall I be liable for any damages whatsoever
(including, without limitation, damages for loss of business profits, business interruption,
loss of business information, or other pecuniary loss) arising out of the use of or inability
to use the script or documentation.
Acknowledgements   :
Assumptions     : ExecutionPolicy of AllSigned (recommended), RemoteSigned or Unrestricted (not recommended)
Limitations     :
Known issues    :
 .LINK
.EXAMPLE
.\
   Description
———–
.INPUTS
None. You cannot pipe objects to this script.
#>
[CmdletBinding(SupportsShouldProcess = $True, SupportsPaging = $True)]
param(
# Complete path and file name to the file to be downloaded
[parameter(ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[ValidateNotNullOrEmpty()]
[string] $SourceFile,
  # The folder where the downloaded file should be placed. If not defined, it defaults to $TargetFolder.
[parameter(ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[string] $DestFolder,
  # The file name the downloaded file should be changed to. If not defined, file maintains it’s original name.
[parameter(ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[string] $DestFile,
  # Whether to download even if a local copy exists. This is useful for files that are updated often and need to be redownloaded.
[parameter(ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[switch] $IgnoreLocalCopy
)
[bool] $HasInternetAccess = ([Activator]::CreateInstance([Type]::GetTypeFromCLSID([Guid]'{DCB00C01-570F-4A9B-8D69-199FDBA5723B}’)).IsConnectedToInternet)
Test-IsProxyEnabled
# I should switch this to using a param block and pipelining from property name – just for consistency
 if (-not($DestFolder)){
$DestFolder = $TargetFolder
}
Set-ModuleStatus -name BitsTransfer
if (-not($DestFile)){
[string] $DestFile = ($SourceFile | Split-Path -leaf)
[Reflection.Assembly]::LoadWithPartialName(“System.Web”) | Out-Null
$DestFile = [System.Web.HttpUtility]::UrlDecode($DestFile)
}
if (Test-Path $DestFolder){
Write-Log -Message “Target folder `”$DestFolder`” exists – no need to create” -NoConsole -Indent 1
} else {
Write-Log -Message “Folder `”$DestFolder`” does not exist, creating…” -NoConsole
New-Item $DestFolder -type Directory | Out-Null
Write-Log -Message “Done!” -NoConsole -Indent 1
}
if ((Test-Path “$DestFolder\$DestFile”) -and (-not $IgnoreLocalCopy)){
if ($(((Get-Item $DestFolder\$DestFile).VersionInfo).FileVersion)){
Write-Log -Message “File `”$DestFile`” version $(((Get-Item $DestFolder\$DestFile).VersionInfo).FileVersion) exists locally – no need to download” -NoConsole
}else{
Write-Log -Message “File `”$DestFile`” exists locally – no need to download” -NoConsole
}
} else {
if ($HasInternetAccess){
Write-Log -Message “Internet access available” -NoConsole -Indent 1
if (-not $IgnoreLocalCopy){
Write-Log -Message “File `”$DestFile`” does not exist in `”$DestFolder`”” -NoConsole -Indent 1
} else {
Write-Log -Message “Forcing download of `”$DestFile`” to `”$DestFolder`”” -NoConsole
}
Write-Log -Message “Downloading `”$SourceFile`” to `”$DestFolder`”” -NoConsole -Indent 1
########################################################################################################
# NOTE: Default parameters may have been changed due to proxy settings. See Test-IsProxyEnabled function
########################################################################################################
# determine file size before downloading
<#
$clnt = New-Object System.Net.WebClient
$clnt.OpenRead($SourceFile) | Out-Null
$dlfilesize = [int] $($clnt.ResponseHeaders[“Content-Length”]/1mb)
# $dlfilesize
$clnt.Dispose()
#>
if ($dlfilesize){
Start-BitsTransfer -Source “$SourceFile” -Destination “$DestFolder\$DestFile” -Description “Downloading $DestFile ($dlfilesize MB)” -ErrorAction SilentlyContinue
}else{
Start-BitsTransfer -Source “$SourceFile” -Destination “$DestFolder\$DestFile” -Description “Downloading $DestFile” -ErrorAction SilentlyContinue
}
   if (Test-Path $DestFolder\$DestFile){
if ($(((Get-Item $DestFolder\$DestFile).VersionInfo).FileVersion)){
Write-Log -Message “Successfully downloaded $DestFolder\$DestFile version $(((Get-Item $DestFolder\$DestFile).VersionInfo).FileVersion)” -NoConsole -Indent 1
}else{
Write-Log -Message “Successfully downloaded $DestFolder\$DestFile” -NoConsole -Indent 1
}
} else {
Write-Log -Level error -message “Failed! File not downloaded!” -Indent 1
Write-Log -Message “Prompting user to abort/retry/ignore” -NoConsole
switch (New-Popup -message “A file download failure has occurred. What would you like to do?” -Title “Download error!” -Buttons “AbortRetryIgnore” -Icon Exclamation){
3{ # abort
Write-Log -Message “User has chosen to abort script” -NoConsole -Indent 1
Stop-Script
exit
}
4{ # retry
Write-Log -Message “User has chosen to retry” -NoConsole -Indent 1
Write-Log -Message “Building retry expression” -NoConsole -Indent 2
if ($IgnoreLocalCopy){
$DownloadRetry += ” -IgnoreLocalCopy”
}
if ($DestFile){
$DownloadRetry += ” -DestFile $Destfile”
}
if ($DestFolder){
$DownloadRetry += ” -DestFolder $DestFolder”
}
$DownloadRetryExp = “New-FileDownload -SourceFile $SourceFile”+ $DownloadRetry
Write-Log -Message “Retry expression is $DownloadRetryExp” -NoConsole -Indent 2
Invoke-Expression $DownloadRetryExp
}
5{ # ignore
Write-Log -Message “User has chosen to ignore” -NoConsole -Indent 1
}
}
}
} else {
Write-Log -Level warn -Message “Internet access not detected.”
Write-Log -Level warn -Message “This can be because there is no Internet connection,”
Write-Log -Level warn -Message “there is no DNS resolution,”
Write-Log -Level warn -Message “or a proxy is in place. Please resolve and try again.”
Write-Log -Level warn -Message “Alternatively, you can manually download the file ($SourceFile)”
Write-Log -Level warn -Message “and place it in $DestFolder and try again.”
}
}
} # end function New-FileDownload
function New-ProgramInstallation {
<#
.SYNOPSIS
Runs silent installation of programs, including install switches.
 .DESCRIPTION
Runs silent installation of programs, including install switches. Script can wait for processes and/or registry values to exist before continuing.
 .NOTES
Version       : 1.2
Wish list      : Better error trapping
Rights Required   : Local administrator on server
Sched Task Required : No
Lync Server Version : N/A
Author/Copyright  : © Pat Richard, Lync MVP – All Rights Reserved
Email/Blog/Twitter : pat@innervation.com  http://www.ehloworld.com @patrichard
Dedicated Post   :
Disclaimer       : You running this script means you won’t blame me if this breaks your stuff. This script is
provided AS IS without warranty of any kind. I disclaim all implied warranties including,
without limitation, any implied warranties of merchantability or of fitness for a particular
purpose. The entire risk arising out of the use or performance of the sample scripts and
documentation remains with you. In no event shall I be liable for any damages whatsoever
(including, without limitation, damages for loss of business profits, business interruption,
loss of business information, or other pecuniary loss) arising out of the use of or inability
to use the script or documentation.
Acknowledgements   :
Assumptions     : ExecutionPolicy of AllSigned (recommended), RemoteSigned or Unrestricted (not recommended)
Limitations     :
Known issues    :
 .LINK
.EXAMPLE
New-ProgramInstallation -InstallFile “c:\installer.msi” -InstallSwitches “/qb”
   Description
———–
Runs installer.msi with the /qb switches
 .EXAMPLE
New-ProgramInstallation -InstallFile “c:\installer.msi” -InstallSwitches “/qb” -WaitForProcessName “MyProgramInstaller”
   Description
———–
Runs installer.msi with the /qb switches, and waits for the process called MyProgramInstaller to stop before continuing
 .EXAMPLE
New-ProgramInstallation -InstallFile “c:\installer.msi” -InstallSwitches “/qb” -WaitForRegistryEntry “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{90150000-1151-0000-1000-0000000FF1CE}”
  Description
———–
Runs installer.msi with the /qb switches, and waits for the registry entry to be written before continuing
 .INPUTS
None. You cannot pipe objects to this script.
#>
[CmdletBinding(SupportsShouldProcess = $True, SupportsPaging = $True)]
param (
# Complete path and file name of the file to be executed.
[parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Mandatory = $true, HelpMessage = “No installation file specified”)]
[ValidateNotNullOrEmpty()]
[string] $InstallFile,
  # Any special command line switches to be used when executing the file.
[parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[string] $InstallSwitches,
  # If defined, the function will wait until the named process ends
[parameter(ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[string] $WaitForProcessName,
  # If defined, the function will wait until the named registry value exists
[parameter(ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[ValidatePattern(“^HKLM:|^HKCU:”)]
[string] $WaitForRegistryEntry,
  # If defined, the function will wait until the named path exists
[parameter(ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[string] $WaitForPath,
  # If specified, will display $LongInstallMessage to notify that this installation will take some time
[parameter(ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[switch] $LongInstall,
  # Text that is displayed if the installation will take a while.
[parameter(ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)]
[string] $LongInstallMessage = “(this may take several minutes)”
)
$error.clear()
if (Test-Path $InstallFile){
Write-Log -Message “File exists” -NoConsole -Indent 1
# $DestFile = $InstallFile.Substring($InstallFile.LastIndexOf(“\”) + 1)
$DestFile = $($InstallFile | Split-Path -leaf)
if (-not $LongInstall){
Write-Log -Message “Installing `”$DestFile`””
}else{
Write-Log -Message “Installing `”$DestFile`” $LongInstallMessage”
}
$Install = $InstallFile+” “+$InstallSwitches
Write-Log -Message “Installation command line: `”$install`”” -NoConsole -Indent 1
    # Invoke-Command might work here if we don’t need to evaluate an expression
    Invoke-Expression $Install
# Start-Process -FilePath $InstallFile -ArgumentList $InstallSwitches -Wait
  if ($WaitForPath){
Write-Log -Message “Waiting for path `”$WaitForPath`” to exist” -NoConsole -Indent 1
do {Start-Sleep -Seconds 1} while (-not(Test-Path “$WaitForPath”))
Write-Log -Message “Path `”$WaitForPath`” exists” -NoConsole -Indent 1
}
  if ($WaitForRegistryEntry){
Write-Log -Message “Waiting for registry entry `”$WaitForRegistryEntry`” to be written” -NoConsole -Indent 1
do {Start-Sleep -Seconds 1} while (-not(Test-Path “$WaitForRegistryEntry”))
Write-Log -Message “Registry entry `”$WaitForRegistryEntry`” has been written” -NoConsole -Indent 1
}
  if ($WaitForProcessName){
Start-Sleep -s 1
Write-Log -Message “Waiting for process `”$WaitForProcessName`” to finish running” -NoConsole -Indent 1
Wait-Process -Name $WaitForProcessName
# do {Start-Sleep -Seconds 1} while (Get-Process -ProcessName “$WaitForProcessName” -ErrorAction SilentlyContinue)
Write-Log -Message “`”$WaitForProcessName`” is no longer running” -NoConsole -Indent 1
}
  if ($error){
Write-Log -Level Error -Message “Failed!” -Indent 1
Write-Log -Level error -Message $error
} else {
Write-Log -Message “Installed” -Indent 1
}
} else {
Write-Log -Level error -message “$DestFile does not exist. Unable to proceed.” -Indent 1
}
} # end function New-ProgramInstallation
$version = “1.3”
[string] $LogPath = “$TargetFolder\logs\$env:ComputerName” + ” {0:yyyy-MM-dd hh-mmtt}.log” -f (Get-Date)
[string] $LogDivider = “——————————“
$urlforAzureShell = “http://az412849.vo.msecnd.net/downloads04/azure-powershell.0.8.16.msi&#8221;
$urlforS4BShell = “” #unknown on 5/7/2015
Do {
Write-Log -Message $LogDivider -NoConsole
Write-Log -Message “Displaying main menu” -NoConsole
#Office 365 module Installation check
$SignIninstall = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |  where { $_.displayname -match “Microsoft Online Services Sign-in Assistant” }
$SignInexpectedversion = “7.250.4556.0”
$AAdinstall = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |  where { $_.displayname -match “Windows Azure Active Directory Module for Windows Powershell” }
$aadexpectedversion = “1.0.0”
$LYOInstall = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |  where { $_.displayname -match “Microsoft Lync Online, Windows PowerShell Module” }
$LYOexpectedVersion = “5.0.8892.0”
$SPOInstall = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |  where { $_.displayname -match “SharePoint Online Management Shell” }
$SPOexpectedVersion = “16.0.4017.1200”
$S4BInstall = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |  where { $_.displayname -match “Skype for Business Online, Windows PowerShell Module” }
$S4BexpectedVersion = “6.0.9276.0”
$azureShellInstall = Get-ItemProperty HKLM:\SOFTWARE\Classes\Installer\Products\7A4D0A6FA7B10684CA58755AA6365B03 -ErrorAction SilentlyContinue
$AzureShellExpectedVersion = “0.8.16” #reports 524304 in the above reg path, but 0.8.16 once imported!!
$AzureShellExpectedVersionProgram = “524304”
## Need to add this checking in later and fix a few things – add the waitforegistry items, etc
$AADLoaded = (get-module msonline)
$LYOloaded = (get-module lynconlineconnector)
$SPOLoaded = (get-module Microsoft.Online.SharePoint.PowerShell)
$azureShellLoaded = (get-module Azure)
$S4BShellLoaded = (get-module )
# On premises install check not needed checking load only
$ADloaded = (get-module ActiveDirectory)
$EXLoaded = (get-module EXCHSESS)
$RTCLoaded = (get-module LYNCSESS)
# Check Microsoft Online Services Sign in Assistant status and set a flag for the execution logic and the menu option  (this one is silent)
if ($SIgnInInstall -and ($SignIninstall.displayversion -eq $SignInexpectedversion)) {
$SignInStatus = “Connect”
$SignInMenuUpdate = ”   Office 365 Sign in Assistant   Installed     $SignInexpectedversion”
} elseif ($SignInInstall -and ($SignIninstall.displayversion -ne $SignInexpectedversion)) {
$SignInStatus = “Upgrade”
#######
#  Waiting on updates
#######
} else {
$SignInStatus = “Install”
$SignInMenuUpdate = ”   Office 365 Sign in Assistant   Not Installed”
$prereq =”Prerequisites”
#######
}
# Check Windows Azure AD Shell status and set a flag for the execution logic and the menu option
if ($AADInstall -and ($aadinstall.displayversion -eq $aadexpectedversion)) {
$AADInstallOption = ”   Windows Azure Active Directory Installed     $aadexpectedversion”
$AADStatus = “Connect”
} elseif ($AADInstall -and ($aadinstall.displayversion -ne $aadexpectedversion)) {
$AADInstallOption = ”   Windows Azure Active Directory Update       $aadinstall.displayversion to $aadexpectedversion”
$AADStatus = “Upgrade”
#######
#  Waiting on updates
#######
} else {
$AADInstallOption = ”   Windows Azure AD PowerShell    Not Installed”
$AADStatus = “Install”
}
# Check Lync Online Shell status and set a flag for the execution logic and the menu option
if ($LYOInstall -and ($LYOinstall.displayversion -eq $LYOexpectedversion)) {
$LYOInstallOption = ”   Lync Online PowerShell         Installed     $LYOexpectedversion”
$LYOStatus = “Connect”
} elseif ($LYOInstall -and ($LYOinstall.displayversion -ne $LYOexpectedversion)) {
$LYOInstallOption = ”   Lync Online PowerShell         Update        $lyoinstall.displayversion to $LYOexpectedversion”
$LYOStatus = “Upgrade”
#######
#  Waiting on updates
#######
} else {
$LYOInstallOption = ”   Lync Online PowerShell         Not Installed”
$LYOStatus = “Install”
}
# Check S4B Online Shell status and set a flag for the execution logic and the menu option
if ($S4BInstall -and ($S4Binstall.displayversion -eq $S4Bexpectedversion)) {
$S4BInstallOption = ”   S4B Online PowerShell          Installed     $S4Bexpectedversion”
$S4BStatus = “Connect”
} elseif ($S4BInstall -and ($S4Binstall.displayversion -ne $S4Bexpectedversion)) {
$S4BInstallOption = ”   S4B Online PowerShell          Update        $S4Binstall.displayversion to $S4Bexpectedversion”
$S4BStatus = “Upgrade”
#######
#  Waiting on updates
#######
} else {
$S4BInstallOption = ”   S4B Online PowerShell          Not Installed”
$S4BStatus = “Install”
}
# Check SharePoint Online Shell status and set a flag for the execution logic and the menu option
if ($SPOInstall -and ($SPOinstall.displayversion -eq $SPOexpectedversion)) {
$SPOInstallOption = ”   SharePoint Online PowerShell   Installed     $SPOexpectedversion”
$SPOStatus = “Connect”
} elseif ($SPOInstall -and ($SPOinstall.displayversion -ne $SPOexpectedversion)) {
$spoinstalldisplayversion = $spoinstall.displayversion
$SPOStatus = “Connect”
$SPOInstallOption = ”   SharePoint Online PowerShell   Installed     $SPOexpectedversion”
# Upcoming feature, in place upgrade
# $SPOInstallOption = ”   SharePoint Online PowerShell   Update        $spoinstalldisplayversion to $SPOexpectedversion”
# $SPOStatus = “Upgrade”
#######
#  Waiting on updates
#######
} else {
$SPOInstallOption = ”   SharePoint Online PowerShell   Not Installed”
$SPOStatus = “Install”
}
# Check Active Directory Administration Tools status and set a flag for the execution logic and the menu option
if (get-module -list activedirectory) {

$ADInstallOption = ”   Active Directory RSAT Tools    Installed”
$ADStatus = “Connect”
} else {
$ADInstallOption = ”   Active Directory RSAT Tools    Not Installed”
$ADStatus = “Install”
}

# Check Azure PowerShell status and set a flag for the execution logic and the menu option
if ($AzureshellInstall -and ($azureshellinstall.version -eq $AzureshellexpectedversionProgram)) {
$AzureshellInstallOption = ”   Azure IaaS PowerShell          Installed     $Azureshellexpectedversion”
$AzureshellStatus = “Connect”
} elseif ($AzureShellInstall -and ($azureshellinstall.version -ne $AzureShellexpectedversion)) {
$AzureshellInstallOption = ”   Azure IaaS PowerShell          Update        $Azureshellexpectedversion”
$AzureshellStatus = “Upgrade”
#######
#  Waiting on updates
#######
} else {
$AzureshellInstallOption = ”   Azure IaaS PowerShell          Not Installed”
$AzureshellStatus = “Install”
}

if ($urlforS4BShell) {
$S4BOption = “6) $S4BStatus Skype for Business Online”
}

[string] $Menu = @”
   ┌──────────────────────────────────────────────────────────┐
|      Microsoft PowerShell Installer and Launcher v$version    |
└──────────────────────────────────────────────────────────┘
   $SignInMenuUpdate
$AADInstallOption
$LYOInstallOption
$SPOInstallOption
$ADInstallOption
$AzureshellInstallOption
$S4BInstallOption
Cloud PowerShell:
1) $AADStatus Azure Active Directory $prereq
2) $LYOStatus Lync/S4B Online
3) $SPOStatus SharePoint Online
4) Connect Exchange Online
5) $AzureShellStatus Azure IaaS
On Premises Remote PowerShell:
6) Connect Exchange
7) Connect Lync or S4B
8) $ADStatus Active Directory
 9)  Set Office 365 Identity for this Session
10) Set On Premises Identity for this Session
 99) Exit
Select an option.. [1-99]?
“@
 $MenuOption = Read-Host $Menu
switch ($MenuOption) {
1{ # Azure AD PowerShell Connect
if ($SignInStatus -eq “Connect”) {
# Do nothing
} elseif ($SignInStatus -eq “Upgrade”) {
#uninstall old version
                    # Need to run the uninstall string here
# Execute $SignIndinstall.UninstallString to uninstall current version
                } elseif ($SignInStatus -eq “Install” -and $prereq -eq “Prerequisites”) {
#install Sign in Assistant
#Install current version
write-host “in here”
if ($env:PROCESSOR_ARCHITECTURE -eq “AMD64”) {
Write-Host “Downloading Office Sign in Assistant for 64 bit..”
New-FileDownload -SourceFile $urlforMSSigninAssistant64
Write-Host “Installing MS Office Sign in Assistant 64 bit…”
Write-Log -Message “Installing MS Office Sign in Assistant 64 bit” -NoConsole -Indent 3
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlforMSSigninAssistant64 | Split-Path -leaf)” -InstallSwitches “/passive” -WaitForRegistryEntry “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{D8AB93B0-6FBF-44A0-971F-C0669B5AE6DD}”
$prereq = “”
} else {
Write-Host “Downloading Office Sign in Assistant for 64 bit..”
New-FileDownload -SourceFile $urlforMSSigninAssistant32
Write-Host “Installing MS Office Sign in Assistant 32 bit…”
Write-Log -Message “Installing MS Office Sign in Assistant 32 bit” -NoConsole -Indent 3
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlforMSSigninAssistant32 | Split-Path -leaf)” -InstallSwitches “/passive” -WaitForRegistryEntry “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{D8AB93B0-6FBF-44A0-971F-C0669B5AE6DD}”
$prereq = “”
}
}
# If pre-req’s are met, go for it
if ($AADStatus -eq “Connect”) {
Import-Module MSOnline
Write-Host “Connecting to Azure AD…”
if ($GlobalCloudCredential) {

Connect-MsolService -Credential $GlobalCloudCredential
} else {
$AADcredential = get-credential -message “Enter your Azure AD Admin Credentials”
Connect-MsolService -Credential $AADcredential
}
} elseif ($AADStatus -eq “Upgrade”) {

                # Need to run the uninstall string here
# Execute $AAdinstall.UninstallString to uninstall current version
#Install current version
            } elseif ($AADStatus -eq “Install”) {
#Install current version
Write-Host “Downloading Azure AD PowerShell…”
New-FileDownload -SourceFile $urlforAadShell
Write-Host “Installing Azure AD PowerShell…”
Write-Log -Message “Installing Azure AD PowerShell” -NoConsole -Indent 2
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlforAadShell | Split-Path -leaf)” -InstallSwitches “/passive” -WaitForRegistryEntry “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{43CC9C53-A217-4850-B5B2-8C347920E500}”
Write-Host “Install Complete, re-select to connect!”
}

}
2{ # Lync Online PowerShell Connect
if ($LYOStatus -eq “Install”) {
# Lync Online PowerShell Install
Write-Host “Downloading Lync Online PowerShell…”
Write-Log -Message “Lync Online PowerShell install selected” -NoConsole -Indent 2
New-FileDownload -SourceFile $urlforLyoShell
Write-Host “Installing Lync Online PowerShell…”
Write-Log -Message “Lync Online PowerShell install beginning” -NoConsole -Indent 2
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlforLyoShell | Split-Path -leaf)” -InstallSwitches “/passive” -WaitForRegistryEntry “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{3DA37B25-64F5-40D6-BB41-D0AB877A4821}”
} elseif ($LYOStatus -eq “Connect”) {
import-module LyncOnlineConnector
Write-Host “Connecting to Lync Online…”
if ($GlobalCloudCredential) {
$LYOsession = New-CsOnlineSession -Credential $GlobalCloudCredential
} else {
$LYOcredential = get-credential -message “Enter your Lync Online Admin Credentials”
$LYOsession = New-CsOnlineSession -Credential $LYOcredential
}
Import-PSSession $LYOsession
}
}
3{ # SharePoint Online PowerShell Connect
if ($SPOStatus -eq “Install”) {
Write-Host “Downloading SharePoint Online PowerShell…”
Write-Log -Message “SharePoint PowerShell install selected” -NoConsole -Indent 2
if ($env:PROCESSOR_ARCHITECTURE -eq “AMD64”) {
New-FileDownload -SourceFile $urlforsposhell64
Write-Host “Installing SharePoint Online PowerShell for 64 bit…”
Write-Log -Message “Installing SharePoint Online PowerShell for 64 bit” -NoConsole -Indent 2
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlforsposhell64 | Split-Path -leaf)” -InstallSwitches “/passive” -WaitForRegistryEntry “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{95160000-115B-0409-1000-0000000FF1CE}”
} else {
New-FileDownload -SourceFile $urlforsposhell32
Write-Host “Installing SharePoint Online PowerShell for 32 bit…”
Write-Log -Message “Installing SharePoint Online PowerShell for 32 bit” -NoConsole -Indent 2
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlforsposhell32 | Split-Path -leaf)” -InstallSwitches “/passive” -WaitForRegistryEntry “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{95160000-115B-0409-1000-0000000FF1CE}”
}

            } elseif ($SPOStatus -eq “Upgrade”) {
# Upcoming feature, in place upgrade
# Upcoming feature, in place upgrade
# Upcoming feature, in place upgrade
<# Write-Host “Upgrading SharePoint Online PowerShell…”
Write-Log -Message “SharePoint PowerShell upgrade selected” -NoConsole -Indent 2
if ($env:PROCESSOR_ARCHITECTURE -eq “AMD64”) {
#Uninstall old x64 version
Write-Host “Downloading SharePoint Online PowerShell…”
New-FileDownload -SourceFile $urlforsposhell64
Write-Host “Installing SharePoint Online PowerShell for 64 bit…”
Write-Log -Message “Installing SharePoint Online PowerShell for 64 bit” -NoConsole -Indent 2
# Update the wait for key
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlforsposhell64 | Split-Path -leaf)” -InstallSwitches “/passive” -WaitForRegistryEntry “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{95160000-115B-0409-1000-0000000FF1CE}”
} else {
#Uninstall old x86 version
Write-Host “Downloading SharePoint Online PowerShell…”
New-FileDownload -SourceFile $urlforsposhell32
Write-Host “Installing SharePoint Online PowerShell for 32 bit…”
Write-Log -Message “Installing SharePoint Online PowerShell for 32 bit” -NoConsole -Indent 2
# Update the wait for key
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlforsposhell32 | Split-Path -leaf)” -InstallSwitches “/passive” -WaitForRegistryEntry “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{95160000-115B-0409-1000-0000000FF1CE}”
}
#>
} elseif ($SPOStatus -eq “Connect”) {
$SPOTenantID = read-host -Prompt “Enter your Office 365 tenantID (The name before the .onmicrosoft.com)”
import-module Microsoft.Online.SharePoint.PowerShell
Write-Host “Connecting to SharePoint Online…”
Write-Log -Message “Sharepoint Online Connection String – $spoconnectionstring” -NoConsole -Indent 2
                $SPOConnectionString = “https://&#8221; + $SPOTenantID + “-admin.sharepoint.com”
if ($GlobalCloudCredential) {
Connect-SPOService -Url $SPOConnectionString -Credential $GlobalCloudCredential
} else {
$SPOcredential = get-credential -message “Enter your SharePoint Online Admin Credentials”
Connect-SPOService -Url $SPOConnectionString -Credential $SPOcredential
}
}
}
        4{ # Exchange Online PowerShell Connect
Write-Host “Connecting to Exchange Online…”
if ($GlobalCloudCredential) {
$EXOSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $globalcloudcredential -Authentication Basic -AllowRedirection
} else {
$EXOcredential = get-credential -message “Enter your Exchange Online Admin Credentials”
$EXOSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $EXOCredential -Authentication Basic -AllowRedirection
}
Import-PSSession $EXOsession
}
        5{ #Azure iAAS PowerShell
if ($AzureShellStatus -eq “Install”) {
Write-Host “Downloading Azure IaaS PowerShell…”
Write-Log -Message “Azure IaaS PowerShell install selected” -NoConsole -Indent 2
New-FileDownload -SourceFile $urlforAzureShell
Write-Host “Installing Azure IaaS PowerShell…”
Write-Log -Message “Installing Azure IaaS PowerShell” -NoConsole -Indent 2
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlforAzureShell | Split-Path -leaf)” -InstallSwitches “/passive” -WaitForRegistryEntry “HKLM:\SOFTWARE\Classes\Installer\Products\7A4D0A6FA7B10684CA58755AA6365B03”
} elseif ($AzureShellStatus -eq “Connect”) {
Write-Host “Connecting to Azure IaaS…”

if ($GlobalCloudCredential) {
Add-Azureaccount -Credential $GlobalCloudCredential
} else {
$AzureShellcredential = get-credential -message “Enter your Azure IaaS Admin Credentials”
Add-Azureaccount -Credential $AzureShellcredential
}
}
}

  <#6{ # S4B Online PowerShell Connect
if ($S4BOStatus -eq “Install”) {
# S4B Online PowerShell Install
Write-Host “Downloading S4B Online PowerShell…”
Write-Log -Message “S4B Online PowerShell install selected” -NoConsole -Indent 2
New-FileDownload -SourceFile $urlforS4BShell
Write-Host “S4B S4B Online PowerShell…”
Write-Log -Message “Lync Online PowerShell install beginning” -NoConsole -Indent 2
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlforS4BShell | Split-Path -leaf)” -InstallSwitches “/passive” -WaitForRegistryEntry “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{D7334D5D-0FA2-4DA9-8D8A-883F8C0BD41B}”
} elseif ($S4BStatus -eq “Connect”) {
import-module SkypeOnlineConnector  #
Write-Host “Connecting to S4B Online…”
if ($GlobalCloudCredential) {
$S4Bsession = New-CsOnlineSession -Credential $GlobalCloudCredential
} else {
$S4Bcredential = get-credential -message “Enter your S4B Online Admin Credentials”
$S4Bsession = New-CsOnlineSession -Credential $S4Bcredential
}
Import-PSSession $S4Bsession
}
}
#>
#
# On Premises
#
6{ # Exchange On Premises PowerShell Connect
$EXServer = read-host -Prompt “Enter Exchange Server Name to connect to”
$EXConnectionUri = “http://&#8221; + $EXserver + “/PowerShell/”
$exsessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
if ($GlobalOnPremisesCredential) {
$EXSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $EXConnectionURI -Authentication Kerberos -Credential $GlobalOnPremisesCredential -SessionOption $exsessionOption
} else {
$EXcredential = get-credential -message “Enter your Exchange Admin Credentials”
$EXSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $EXConnectionURI -Authentication Kerberos -Credential $EXcredential -Name “EXCHSESS” -SessionOption $exsessionOption
}
Import-PSSession $EXsession
}
7{ # Lync/S4B On Premises PowerShell Connect
$LyncServer = read-host -Prompt “Enter Lync or S4B Front End Server Name to connect to”
$LyncConnectionUri = “https://&#8221; + $LyncServer + “/OCSPowerShell/”
$LyncsessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
if ($GlobalOnPremisesCredential) {
$LyncSession = New-PSSession -ConnectionUri $LyncConnectionURI -Authentication Negotiate -Credential $globalOnPremisesCredential -SessionOption $LyncsessionOption
} else {
$LyncCredential = get-credential -message “Enter your Lync Admin Credentials”
                $LyncSession = New-PSSession -ConnectionUri $LyncConnectionURI -Authentication Negotiate -Credential $LyncCredential -Name “LYNCSESS” -SessionOption $LyncsessionOption
}
Import-PSSession $LyncSession
}
8{ # Active Directory On Premises PowerShell Connect
if ($ADstatus -eq “Install”) {
Write-Host “Downloading AD Remote Admin Tools”
Write-Log -Message “AD Remote Admin Tools install selected” -NoConsole -Indent 2
$ADStatus =”Connect”
if ((Get-WmiObject -Class win32_operatingsystem).caption -match “Windows 8 “) {
if ($env:PROCESSOR_ARCHITECTURE -eq “AMD64”) {
New-FileDownload -SourceFile $urlforRSAT64
Write-Host “Installing AD Remote Admin Tools for Windows 8.0 64 bit…”
Write-Log -Message “Installing AD Remote Admin Tools for Windows 8.0 64 bit” -NoConsole -Indent 3
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlforRSAT64 | Split-Path -leaf)” -InstallSwitches “/quiet /promptrestart”
& dism.exe /Online /Enable-Feature /FeatureName:RemoteServerAdministrationTools  /FeatureName:RemoteServerAdministrationTools-Roles /FeatureName:RemoteServerAdministrationTools-Roles-AD  /FeatureName:RemoteServerAdministrationTools-Roles-AD-Powershell
} else {
New-FileDownload -SourceFile $urlforRSAT32
Write-Host “Installing AD Remote Admin Tools for Windows 8.0 32 bit…”
Write-Log -Message “Installing AD Remote Admin Tools for Windows 8.0 32 bit” -NoConsole -Indent 3
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlforRSAT32 | Split-Path -leaf)” -InstallSwitches “/quiet /promptrestart”
& dism.exe /Online /Enable-Feature /FeatureName:RemoteServerAdministrationTools  /FeatureName:RemoteServerAdministrationTools-Roles /FeatureName:RemoteServerAdministrationTools-Roles-AD  /FeatureName:RemoteServerAdministrationTools-Roles-AD-Powershell
}
} elseif ((Get-WmiObject -Class win32_operatingsystem).caption -match “Windows 8.1”) {
if ($env:PROCESSOR_ARCHITECTURE -eq “AMD64”) {
New-FileDownload -SourceFile $urlfor81RSAT64
Write-Host “Installing AD Remote Admin Tools for Windows 8.1 64 bit…”
Write-Log -Message “Installing AD Remote Admin Tools for Windows 8.1 64 bit” -NoConsole -Indent 3
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlfor81RSAT64 | Split-Path -leaf)” -InstallSwitches “/quiet /promptrestart”
& dism.exe /Online /Enable-Feature /FeatureName:RemoteServerAdministrationTools  /FeatureName:RemoteServerAdministrationTools-Roles /FeatureName:RemoteServerAdministrationTools-Roles-AD  /FeatureName:RemoteServerAdministrationTools-Roles-AD-Powershell
} else {
New-FileDownload -SourceFile $urlfor81RSAT32
Write-Host “Installing AD Remote Admin Tools for Windows 8.1 32 bit…”
Write-Log -Message “Installing AD Remote Admin Tools for Windows 8.1 32 bit” -NoConsole -Indent 3
New-ProgramInstallation -InstallFile “$TargetFolder\$($urlfor81RSAT32 | Split-Path -leaf)” -InstallSwitches “/quiet /promptrestart”
& dism.exe /Online /Enable-Feature /FeatureName:RemoteServerAdministrationTools  /FeatureName:RemoteServerAdministrationTools-Roles /FeatureName:RemoteServerAdministrationTools-Roles-AD  /FeatureName:RemoteServerAdministrationTools-Roles-AD-Powershell
                }
            } elseif ($ADstatus -eq “Connect”) {
import-module ActiveDirectory
}
}
}
9{ # Set Cloud Credential
write-host “Collecting Office 365 credentials  for this session”
$GlobalCloudCredential = Get-Credential -Message “Please enter your global admin credentials for all Office 365 services”
}
        10{ # Set On premises Credential
write-host “Collecting on premises credentials for this session”
$GlobalOnPremisesCredential = Get-Credential -Message “Please enter your Enterprise Admin and/or Exchange/Lync Admin for On Premises Services”
}
}
} while ($MenuOption -notmatch {^99$|^x$})
Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s