Binding the SSL certificate to my site works in powershell ise in admin mode but not from PowerShell 7 in admin mode - powershell-7.0

I am trying to bind the SSL certificate to my site. If I run the script from PowerShell ise in admin mode it works fine however, when I run from PowerShell 7 in admin mode, it does not bind the certificate to the site. I am using the below section in my script:
#Add SSL Certificate
if(($Protocol -eq "https") -and ($Port) -and ($AddConfiguration))
{
$newWebBindingCmd = "New-WebBinding -Name '$Name' -Protocol 'https' -Port '$port' -SslFlags 1"
$getWebBindingCmd = "Get-WebBinding -Name '$Name' -Port '$port'"
if($IPAddress)
{
$newWebBindingCmd += " -IPAddress '$IpAddress'"
$getWebBindingCmd += " -IPAddress '$IpAddress'"
}
If($hostname)
{
$newWebBindingCmd += " -HostHeader '$hostname'"
}
if (-not([string]::IsNullOrEmpty($CertificateKey)))
{
$cert = Get-ChildItem 'Cert:\LocalMachine\My' | where {($_.Subject -like "*$CertificateKey*") -or ($_.Thumbprint -like "*$CertificateKey*")};
if($cert -ne $null)
{
write-host 'Certificate Found';
$CommandLines = "Import-Module WebAdministration;$newWebBindingCmd;"
$createhttpsbinding = Execute-CommandLines -Commandlines $CommandLines.ToString();
if($createhttpsbinding -eq $true)
{
write-host 'https binding created successfully';
}
$CommandLines = "Import-Module WebAdministration;
`$httpsbinding = $getWebBindingCmd -Protocol 'https';
if(`$httpsbinding)
{
`$httpsbinding.AddSslCertificate(`$cert.GetCertHashString(), 'my');
write-host 'Added SslCertificate successfully';
}";
$addSslCertificate = Execute-CommandLines -Commandlines $CommandLines.ToString();
if($addSslCertificate -eq $true)
{
$CommandLines = "Import-Module WebAdministration;$getWebBindingCmd -Protocol 'http' | Remove-WebBinding;"
write-host 'SslCertificate installed. Removing http binding..';
}
else
{
$CommandLines = "Import-Module WebAdministration;$getWebBindingCmd -Protocol 'https' | Remove-WebBinding;"
write-host 'SslCertificate could not be installed. Removing https binding..';
}
$result = Execute-CommandLines -Commandlines $CommandLines.ToString()
if($result -eq $true)
{
Log -color Green "Binding Properties set successfully for WebService '$Name'"
}
else
{
Log -color Red "Binding Properties could not be set for WebService '$Name'"
}
}
else
{
Log -color Red "Certificate with CertificateKey '$CertificateKey' is not found!"
}
}
}

Related

Trying to use remote variable in If-Condition within ScriptBlock using PowerShell

I am trying to use below code to remove the groups from Active Directory. I am maintaining an input file for the list of servers. the input file is in the local machine and trying to use the content of the file inside the ScriptBlock using ($Using:variablename) after taking a remote session.
I am getting the content[file content] of the variable inside the ScriptBlock which is defined outside the ScriptBlock. The issue is the if condition [if($serverlist -ne $null)] is satisfying even if the variable is empty. The code is entering into if block even if the variable $serverlist is null, instead it has to take else block.
Could you please help me on this.
$adserver = Read-Host -Prompt "Please enter AD server details"
$adserver
$askcredential = $host.ui.PromptForCredential("Need credentials", "Please enter your user name and password.", "", "NetBiosUserName")
$credential = New-Object System.Management.Automation.PsCredential($askcredential.UserName,$askcredential.Password)
$session = New-PSSession -ComputerName "$adserver" -Credential $credential
#$command = (Get-ADForest).domains
$addomain = Read-Host -Prompt "Please enter the Domain"
$servers = Get-Content "D:\Bhargavi\Windows-Decommission\$addomain\servers.txt"
#Invoke-Command -ComputerName $adserver -Authentication Default -Credential $credential -ScriptBlock {
Invoke-Command -Session $session -ScriptBlock {
#$addomain = Read-Host -Prompt "Please enter the Domain"
#$servers = Get-Content "D:\Bhargavi\Windows-Decommission\$addomain\servers.txt"
#Param($domainname,$serverlist)
$serverlist = $Using:servers
$domainname = $Using:addomain
Write-Host "the list is $serverlist"
Write-Host "the domain is $domainname"
if($serverlist -ne $null)
{
Write-Host "Found the data in the input file. Proceeding to remove the groups."
foreach ($server in $serverlist)
{
write-host "Server Name is: $server"
$mgserver = "MG-$server"
$mggroup = Get-ADGroup -Filter { Name -like $mgserver }
$mggroup
if($mggroup -ne $null)
{
Get-ADGroup -Filter { Name -like $mgserver } #| Remove-ADGroup -Confirm:$False
$mggroupconfirm = Get-ADGroup -Filter { Name -like $mgserver }
if($mggroupconfirm -eq $null)
{
Write-Host "$mgserver is removed from $domainname"
#Set-Content -Path "D:\Bhargavi\Windows-Decommission\$domainname\servers.txt" -Value (get-content -Path "D:\Bhargavi\Windows-Decommission\$domainname\servers.txt" | Select-String -Pattern "$server" -NotMatch)
}
else
{
Write-Host "$mgserver is not removed. Please try again."
}
}
else{Write-Host "There is no group called $mgserver in $domainname domain "}
}
}
else
{
DO
{
$val = Read-Host -Prompt "Do you want to enter servername ? Enter yes or no"
if($val -eq "yes")
{
$entermgserver = Read-Host -Prompt "Please enter the server name"
$entermgserver
$mgserver = "MG-$entermgserver"
$mgserver
$mggroup = Get-ADGroup -Filter { Name -like $mgserver }
$mggroup
if($mggroup -ne $null)
{
#Write-Host "$mggroup is not null"
Get-ADGroup -Filter { Name -like $mgserver } #| Remove-ADGroup -Confirm:$False
$mggroupconfirm = Get-ADGroup -Filter { Name -like $mgserver }
if($mggroupconfirm -eq $null)
{
Write-Host "$mgserver is removed"
}
else
{
Write-Host "$mgserver is not removed. Please try again."
}
}
else{Write-Host "The is no group called $mgserver in $domainname domain"}
}
}until ($val -eq "no")
}
} ### End Script Block
Clear-Content "D:\Bhargavi\Windows-Decommission\$addomain\servers.txt"
Remove-PSSession -Session $session

powershell - how to auto add and remove dhcp reservation with csv

my client.csv format is:
ScopeId,Name,ClientId,Ipaddress
10.10.10.0,Computer1,1a-1b-1c-1d-1e-1f,10.10.10.10
10.10.10.0,Computer2,2a-2b-2c-2d-2e-2f,10.10.10.11
10.10.10.0,Computer3,3a-3b-3c-3d-3e-3f,10.10.10.12
my client.csv format (when the user's ClientID is null):
ScopeId,Name,ClientId,Ipaddress
10.10.10.0,Computer1,1a-1b-1c-1d-1e-1f,10.10.10.10
10.10.10.0,Computer2,2a-2b-2c-2d-2e-2f,10.10.10.11
10.10.10.0,Computer3,,10.10.10.12
and then run my powershell with my csv,auto add dhcp server reservations is successful,but when the user's ClientID is null ,powershell could not auto remove dhcp server rereservations,my powershell script has some problem?
$ComputerName="WIN-OO4RE715BV8.test.com"
if (!$args) {
Write-Host "client.csv"
}
ELSE
{
$dhcpdata=Import-CSV $args
foreach ($dhcp in $dhcpdata){
$ScopeId=$dhcp.ScopeId
$Name=$dhcp.Name
$ClientId=$dhcp.ClientId
$IPAddress=$dhcp.IPAddress
if ($ClientId -eq $null) {
Remove-DhcpServerv4Reservation -ScopeId $ScopeId -Name $Name -ClientId $ClientId -IPAddress $IPAddress
}
Add-DhcpServerv4Reservation -ScopeId $ScopeId -Name $Name -ClientId $ClientId -IPAddress $IPAddress
}
}
$ComputerName="WIN-JA5I029SJFM.test.com"
if(!$args){
Write-Host "client.csv"
}
ELSE
{
$dhcpdata=Import-CSV $args
foreach ($dhcp in $dhcpdata){
$ScopeId=$dhcp.ScopeId
$Name=$dhcp.Name
$ClientId=$dhcp.ClientId
$IPAddress=$dhcp.IPAddress
Add-DhcpServerv4Reservation -ScopeId $ScopeId -Name $Name -ClientId $ClientId -
IPAddress $IPAddress
if(!$ClientId)
{
echo Remove-DhcpServerv4Reservation -ComputerName "$ComputerName" -IPAddress
$IPAddress
Remove-DhcpServerv4Reservation -ComputerName "$ComputerName" -IPAddress
$IPAddress
}
}
}

Returning data calling function from invoke-command with parameters

Apologize for the length..
Trying to modify a script that currently uses robocopy to report a folder path's size, child folder count, and size. This script currently takes about 24 hrs to run as it goes one by one to each folder. I'm trying to implement invoke-command to set-up jobs so that it will run at least 10 instances of robocopy in the hopes if drastically reducing run time.
I've tried multiple variances given multiple resources to set parameters, call a function and get the results back with no success.
with current code (below) getting error;
Invoke-Command : Parameter set cannot be resolved using the specified named parameters.
ERROR: + Invoke-Command -ScriptBlock { param ($item,$Filter,$params) $ ...
ERROR: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ERROR: + CategoryInfo : InvalidArgument: (:) [Invoke-Command], ParameterBindingException
ERROR: + FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands.InvokeCommandCommand
Function ListFolder ($Folder, $FilterSet, $Roboparam)
{
write-host $Folder
Try
{
$Folder = (Resolve-Path -LiteralPath $Folder -ErrorAction Stop).ProviderPath
If (-Not (Test-Path -LiteralPath $Folder -Type Container -ErrorAction Stop))
{Write-Warning ("{0} is not a directory and will be skipped" -f $Folder)
Return
}
$Script = robocopy $Folder NULL $FilterSet $FRoboparam
$exit_code = $LASTEXITCODE
16, 8, 4, 2, 1 | % {
Switch ($exit_code -band $_)
{
16 { $exit_reason = "Usage error or insufficient access privileges" }
8 { $exit_reason = "Retry limit exceeded" }
4 { $exit_reason = "Some Mismatched files or directories were detected" }
2 { $exit_reason = "Some Extra files or directories were detected. No files were copied" }
1 { $exit_reason = " " }
}
}
If ($exit_code -eq 0)
{$exit_reason = 'No Change'}
If ($Script[-6] -match $dirPattern)
{$Dir = $matches.Dir}
Else
{$Dir = 0}
If ($Script[-5] -match $countPattern)
{$Count = $matches.Count}
Else
{$Count = 0}
If ($Count -gt 0)
{If ($Script[-4] -match $sizePattern)
{$FSize = $matches.Size}}
Else
{$FSize = 0}
$Script:TotSize += $FSize
$Script:Report += New-Object PSObject -Property #{
'Folder Name' = $Folder
Files = "{0:N0}" -f [int]$Count
Folders = "{0:N0}" -f [int]$Dir
Size = "{0:N0}" -f [long]$FSize
Comment = $exit_reason}
Clear-Variable -Name Dir
Clear-Variable -Name Count
Clear-Variable -Name FSize
If ($exit_reason) { Clear-Variable -Name exit_reason }}
Catch
{$Script:Report += New-Object PSObject -Property #{
'Folder Name' = $Folder
Files = "{0:N0}" -f [int]$Count
Folders = "{0:N0}" -f [int]$Dir
Size = [long]$FSize
Comment = [string]$_.Exception.Message}
Continue
}
Return #$Script
}
}
$params = New-Object System.Collections.Arraylist
$params.AddRange(#("/L","/S","/NJH","/BYTES","/FP","/NFL","/NC","/NDL","/TS","/XJ","/R:0","/W:0"))
$dirPattern = "^\s{4}Dirs\s:\s+(?<Dir>\d+).*"
$countPattern = "^\s{3}Files\s:\s+(?<Count>\d+).*"
$sizePattern = "^\s{3}Bytes\s:\s+(?<Size>\d+(?:\.?\d+)).*"
If ($PSBoundParameters['Force']) {$FileDate = 10}
If ($FileDate -lt 6){Exit}
Else
{$Paths = Get-Content $InputFile
ForEach ($item in $Paths)
{
$MaxThreads = 10
While (#(Get-Job | where { $_.State -eq "Running" }).Count -ge $MaxThreads)
{
Write-Host "Waiting for open thread...($MaxThreads Maximum)"
Start-Sleep -Seconds 3
}
Invoke-Command -Computer . -ScriptBlock { param ($item,$Filter,$params) ${function:ListFolder} } -ArgumentList $item, $Filter, $params -AsJob
}
}
When all said and done I have a collection of $Report to show folder name, count of files, count of folders, size in bytes, and comments tho show any errors to Excel
$Report | Sort-Object {[long]$_.Size} -descending | Select 'Folder Name', Files, Folders, Size, Comment | Export-Csv -Path $ReportPath\$(Get-Date -uformat "%Y_%m_%d")-FileSizes.csv -Encoding ascii -NoTypeInformation

Is it possible to load all functions of a script before it runs?

I have a rather complex script, which follows the following steps;
-->Login (Ask user to enter admin details)
--->Start (Queries Ad for user creditals)
--->Progress (Creates a progress bar)
--->Search (Carries out the search for the data)
--->Question1 -(Yes - Select-Folder No - Create)
--->Select-Folder (Asks the user to create a file path for the document to be stored)
--->Go (Creates a csv from the results of the search)
--->Question2 (CSV - Result XLSX - Excel) (Asks the user if they wish to create a Xlsx file from the Csv)
--->Create (Checks to see if file path exists C:\temp\Server_shares if not creates it)
--->Done (creates csv at default location C:\temp\Server_shares)
--->Question2 (Asks the user if they wish to create a Xlsx file from the Csv)
--->Question2 -(CSV - Result XLSX - Excel) (Asks the user if they wish to create a Xlsx file from the Csv)
--->Result (User has chosen not to create a Xlsx notifys the user of the file path)
--->End (Closes script)
--->Excel (creates Xlsx from csv and stores it in either default or user defined location)
--->Delete (Deletes all remaingin Csv's from file path)
--->End (Closes script)
it seems that I keep get unhandelled exception errors everytime that I run the code.
I have found out that it runs then loads the functions, I need to run them all in memory so that when called each one will run without error.
I have tried creating varibles for each function, but this exactly the same as what I have already.
[void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void][System.Reflection.Assembly]::LoadWithPartialName ("Microsoft.VisualBasic")
$Script:ErrorActionPreference = "Stop"
$Script:Ma3 = "C:\Temp\Server_Shares\"
Function Get-Event{
Function Get-Login {
Clear-Host
#Write-Host "Please provide admin credentials (for example DOMAIN\admin.user and your password)"
$Global:Credential = Get-Credential
}
Function Get-Start{
#Get user credentials
$Cred = Get-Credential -Message "Enter Your Credentials (Domain\Username)"
if ($Cred -eq $Null)
{
Write-Host "Please enter your username in the form of Domain\UserName and try again" -BackgroundColor Black -ForegroundColor Yellow
Rerun
Break
}
#Parse provided user credentials
$DomainNetBIOS = $Cred.username.Split("{\}")[0]
$UserName = $Cred.username.Split("{\}")[1]
$Password = $Cred.GetNetworkCredential().password
Write-Host "`n"
Write-Host "Checking Credentials for $DomainNetBIOS\$UserName" -BackgroundColor Black -ForegroundColor White
Write-Host "***************************************"
If ($DomainNetBIOS -eq $Null -or $UserName -eq $Null)
{
Write-Host "Missing domain please type in the following format: Domain\Username" -BackgroundColor Black -ForegroundColor Yellow
Rerun
Break
}
# Checks if the domain in question is reachable, and get the domain FQDN.
Try
{
$DomainFQDN = (Get-ADDomain $DomainNetBIOS).DNSRoot
}
Catch
{
Write-Host "Error: Domain was not found: " $_.Exception.Message -BackgroundColor Black -ForegroundColor Red
Write-Host "Please make sure the domain NetBios name is correct, and is reachable from this computer" -BackgroundColor Black -ForegroundColor Red
Rerun
Break
}
#Checks user credentials against the domain
$DomainObj = "LDAP://" + $DomainFQDN
$DomainBind = New-Object System.DirectoryServices.DirectoryEntry($DomainObj,$UserName,$Password)
$DomainName = $DomainBind.distinguishedName
If ($DomainName -eq $Null)
{
Write-Host "Domain $DomainFQDN was found: True" -BackgroundColor Black -ForegroundColor Green
$UserExist = Get-ADUser -Server $DomainFQDN -Properties LockedOut -Filter {sAMAccountName -eq $UserName}
If ($UserExist -eq $Null)
{
Write-Host "Error: Username $Username does not exist in $DomainFQDN Domain." -BackgroundColor Black -ForegroundColor Red
Rerun
Break
}
Else
{
Write-Host "User exists in the domain: True" -BackgroundColor Black -ForegroundColor Green
If ($UserExist.Enabled -eq "True")
{
Write-Host "User Enabled: "$UserExist.Enabled -BackgroundColor Black -ForegroundColor Green
}
Else
{
Write-Host "User Enabled: "$UserExist.Enabled -BackgroundColor Black -ForegroundColor RED
Write-Host "Enable the user account in Active Directory, Then check again" -BackgroundColor Black -ForegroundColor RED
Rerun
Break
}
If ($UserExist.LockedOut -eq "True")
{
Write-Host "User Locked: " $UserExist.LockedOut -BackgroundColor Black -ForegroundColor Red
Write-Host "Unlock the User Account in Active Directory, Then check again..." -BackgroundColor Black -ForegroundColor RED
Rerun
Break
}
Else
{
Write-Host "User Locked: " $UserExist.LockedOut -BackgroundColor Black -ForegroundColor Green
}
}
Write-Host "Authentication failed for $DomainNetBIOS\$UserName with the provided password." -BackgroundColor Black -ForegroundColor Red
Write-Host "Please confirm the password, and try again..." -BackgroundColor Black -ForegroundColor Red
Rerun
Break
}
Else
{
Write-Host "SUCCESS: The account $Username successfully authenticated against the domain: $DomainFQDN" -BackgroundColor Black -ForegroundColor Green
}
Search
}
Function Rerun {
$Title = "Enter another set of Credentials?"
$Message = "Do you want to try another set of credentials?"
$Yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Try Again?"
$No = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "End Script."
$Options = [System.Management.Automation.Host.ChoiceDescription[]]($Yes, $No)
$Result = $host.ui.PromptForChoice($Title, $Message, $Options, 0)
Switch ($Result)
{
0 {Get-Start}
1 {"End Script."}
}
}
Function Get-Progress{
Try{
{If (Test-Path $PC -ErrorAction Stop) {
Add-Type -assembly System.Windows.Forms
## -- Create The Progress-Bar
$ObjForm = New-Object System.Windows.Forms.Form
$ObjForm.Text = "Progress-Bar of searched folders"
$ObjForm.Height = 100
$ObjForm.Width = 500
$ObjForm.BackColor = "White"
$ObjForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle
$ObjForm.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
## -- Create The Label
$ObjLabel = New-Object System.Windows.Forms.Label
$ObjLabel.Text = "Starting. Please wait ... "
$ObjLabel.Left = 5
$ObjLabel.Top = 10
$ObjLabel.Width = 500 - 20
$ObjLabel.Height = 15
$ObjLabel.Font = "Tahoma"
## -- Add the label to the Form
$ObjForm.Controls.Add($ObjLabel)
$PB = New-Object System.Windows.Forms.ProgressBar
$PB.Name = "PowerShellProgressBar"
$PB.Value = 0
$PB.Style="Continuous"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 500 - 40
$System_Drawing_Size.Height = 20
$PB.Size = $System_Drawing_Size
$PB.Left = 5
$PB.Top = 40
$ObjForm.Controls.Add($PB)
## -- Show the Progress-Bar and Start The PowerShell Script
$ObjForm.Show() | Out-Null
$ObjForm.Focus() | Out-NUll
$ObjLabel.Text = "Starting. Please wait ... "
$ObjForm.Refresh()
Start-Sleep -Seconds 1
Out-Null
## -- Execute The PowerShell Code and Update the Status of the Progress-Bar
$result = (get-acl $pc).Access
$Counter = 0
ForEach ($Item In $Result) {
## -- Calculate The Percentage Completed
$Counter++
[Int]$Percentage = ($Counter/$Result.Count)*100
$PB.Value = $Percentage
$ObjLabel.Text = "Scanning $Folders For $criteria in $PC"
#$ObjLabel.Text = "Found $counter Pst's in $Search"
$ObjForm.Refresh()
Start-Sleep -Milliseconds 150
# -- $Item.Name
#"`t" + $Item.Path
$ObjForm.Close()
#Write-Host "`n"
Else {
#Write-Host
#Write-Host "`t Cannot Execute The Script." -ForegroundColor "Yellow"
#Write-Host "`t $Search Does Not Exist in the System." -ForegroundColor "Yellow"
#Write-Host
}
}
}
}
}
Catch{
Write-Host "Please enter a vaild path" -ForegroundColor Cyan
Search
}
}
Function Script:Get-Question {
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$Form1 = New-Object System.Windows.Forms.Form
$Form1.ClientSize = New-Object System.Drawing.Size(200, 100)
$form1.topmost = $true
$Text = New-Object System.Windows.Forms.Label
$Text.Location = New-Object System.Drawing.Point(15, 15)
$Text.Size = New-Object System.Drawing.Size(200, 40)
$Text.Text = "Would you like to save the file to a custom location?"
$Form1.Controls.Add($Text)
#$ErrorActionPreference = "SilentlyContinue"
Function Button1
{
$Button1 = New-Object System.Windows.Forms.Button
$Button1.Location = New-Object System.Drawing.Point(20, 55)
$Button1.Size = New-Object System.Drawing.Size(55, 20)
$Button1.Text = "Yes"
$Button1.add_Click({Get-Go -ErrorAction SilentlyContinue
$Form1.Close()})
$Form1.Controls.Add($Button1)
}
Function Button2
{
$Button2 = New-Object System.Windows.Forms.Button
$Button2.Location = New-Object System.Drawing.Point(80, 55)
$Button2.Size = New-Object System.Drawing.Size(55, 20)
$Button2.Text = "No"
$Button2.add_Click({Get-Create -ErrorAction SilentlyContinue
$Form1.Close()})
$Form1.Controls.Add($Button2)
}
Button1
Button2
[void]$form1.showdialog()
}
Function Select-FolderDialog{
param([string]$Description="Select Folder",[string] $RootFolder="Desktop")
[System.Reflection.Assembly]::LoadWithPartialName ("System.windows.forms") | Out-Null
Write-host "Please minimize the console to select a folder in which to save the results"
$objForm = New-Object System.Windows.Forms.FolderBrowserDialog
$objForm.Rootfolder = $RootFolder
$objForm.Description = $Description
$objForm.ShowNewFolderButton = $false
$Show = $objForm.ShowDialog()
If ($Show -eq "OK")
{
Return $objForm.SelectedPath
}
Else
{
Write-Error "Operation cancelled by user."
Exit
}
}
Function Get-Search{
Write-host "Please Minimize the console and enter the full folder path that you require permissions for" -ForegroundColor Green
$Script:PC = [Microsoft.VisualBasic.Interaction]::InputBox("Please enter the full path of the folder you wish to search", "Folder choice")
If ($PC -eq "")
{
Exit
}
Get-Progress
$Res = (get-acl $pc).Access
$Script:Gold = $Res| Select-object #{label = "User Groups";Expression = {$_.IdentityReference}},
#{label = "Rights";Expression = {$_.FileSystemRights}},
#{label = "Access";Expression = {$_.AccessControlType}}
Get-Question
}
Function Script:Get-Go{
$Form1.Close()
$FPath = Select-FolderDialog
$Folder = $FPath + "\" + [Microsoft.VisualBasic.Interaction]::InputBox ("Please select a folder to save the data to", "Path Choice") + "\"
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
"Please minimize the console to select a folder in which to save the results"
$Name = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a filename", "File Name Choice")
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
$cfgOutpath = $Folder + "$Name"
if( -Not (Test-Path -Path $Folder ) )
{
New-Item -ItemType directory -Path $Folder |out-null
}
Else{
[System.Windows.MessageBox]::Show('The directory already exists','Error','Ok','Error')
}
$Gold | Export-Csv "$cfgOutpath.csv" -NoClobber -NoTypeInformation
Write-Host "File has been saved to $cfgOutpath.csv" -ForegroundColor Yellow
Get-Q2
}
##############################################
## Testing Phases ##
## Get-Start ##
## ##
##############################################
Search
Function Script:Get-Create {
$Form1.Close()
if( -Not (Test-Path -Path $Ma3 ) )
{
New-Item -ItemType directory -Path $Ma3 |out-null
}
Done
}
Function Script:Get-Done{
$PC2 = ($PC -split '\\')[-1]
$CSV = "C:\Temp\Server_Shares\User access for $PC2"
$cfgOutpath = $CSV
$Gold | Export-Csv "$cfgOutpath.csv" -NoClobber -NoTypeInformation
Get-Q2
}
Function Script:Get-Q2 {
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$Form2 = New-Object System.Windows.Forms.Form
$Form2.ClientSize = New-Object System.Drawing.Size(200, 100)
$form2.topmost = $true
$Text = New-Object System.Windows.Forms.Label
$Text.Location = New-Object System.Drawing.Point(15, 15)
$Text.Size = New-Object System.Drawing.Size(200, 40)
$Text.Text = "Would you like to create an Xlsx document or leave it as csv?"
$Form2.Controls.Add($Text)
$ErrorActionPreference = "SilentlyContinue"
Function Button1
{
$Button1 = New-Object System.Windows.Forms.Button
$Button1.Location = New-Object System.Drawing.Point(20, 55)
$Button1.Size = New-Object System.Drawing.Size(55, 20)
$Button1.Text = "CSV"
$Button1.add_Click({Get-Result
$Form2.Close()})
$Form2.Controls.Add($Button1)}
Function Button2
{
$Button2 = New-Object System.Windows.Forms.Button
$Button2.Location = New-Object System.Drawing.Point(80, 55)
$Button2.Size = New-Object System.Drawing.Size(55, 20)
$Button2.Text = "XLSX"
$Button2.add_Click({Get-Excel
$Form2.Close()})
$Form2.Controls.Add($Button2)
}
Button1
Button2
[void]$form2.showdialog()
}
Function Script:Get-Ans{
$Form2.Close()
Try{
Get-Excel
}
Catch{
Write-Host "Unable to create XSLX please check full path." -ForegroundColor Red
}
}
Function Script:Get-Result{
$Form2.Close()
Write-Host "File has been saved to $CSV.csv" -ForegroundColor Yellow
}
Function Script:Get-Excel{
$RD = $Ma3 + "*.csv"
$CsvDir = $RD
$csvs = dir -path $CsvDir # Collects all the .csv's from the driectory
$outputxls = "$Ma4.Xlsx"
$Excel = New-Object -ComObject excel.application
$Excel.displayAlerts = $false
$workbook = $excel.Workbooks.add()
# Loops through each CVS, pulling all the data from each one
foreach($iCsv in $csvs){
$iCsv
$WN = ($iCsv -Split "\\")[5]
$wn = ($WN -Split " ")[3]
$WN = $WN -replace ".{5}$"
$Excel = New-Object -ComObject excel.application
$Excel.displayAlerts = $false
$Worksheet = $workbook.worksheets.add()
$Worksheet.name = $WN
$TxtConnector = ("TEXT;" + $iCsv)
$Connector = $worksheet.Querytables.add($txtconnector,$worksheet.Range("A1"))
$query = $Worksheet.QueryTables.item($Connector.name)
$query.TextfileOtherDelimiter = $Excel.Application.International(5)
$Query.TextfileParseType =1
$Query.TextFileColumnDataTypes = ,2 * $worksheet.cells.column.count
$query.AdjustColumnWidth =1
$Query.Refresh()
$Query.Delete()
$Worksheet.Cells.EntireColumn.AutoFit()
$Worksheet.Rows.Item(1).Font.Bold = $true
$Worksheet.Rows.Item(1).HorizontalAlignment = -4108
$Worksheet.Rows.Item(1).Font.Underline = $true
$Workbook.save()
}
$Empty = $workbook.worksheets.item("Sheet1")
$Empty.Delete()
$Workbook.SaveAs($outputxls,51)
$Workbook.close()
$Excel.quit()
Write-Host "File has been saved to $outputxls" -ForegroundColor Yellow
Delete
}
Function Script:Delete{
get-childitem $MA3 -recurse -force -include *.txt | remove-item -force #Removes all txt files from final directory
get-childitem $MA3 -recurse -force -include *.csv | remove-item -force #Removes all CSV files from final directory
}
Write-Host "Finished"
}
Get-Event
#Excel-Write'
I know it's a lot of code, but in-order for anyone to replicate the probelm, you will need it all.
I want it to run, first time, everytime, at the moment it take 3-4 tries before its loaded each function into memory.
Put all of your functions into a PowerShell module file.
C:\Module.psm1
And then import that module before anything else in the script:
Import-Module C:\Module.psm1
For larger scripts this makes things more manageable as you can keep your long list of functions separate from the script that calls them.

How can I make a win32 command (sqlcommand) print its output to the console in PowerShell

I have a script that eventually calls this line
& sqlcmd.exe -S $DbHost -d $DbSchema -Q "do some crazy db change here"
Where "do some crazy db change here" will eventually be replaced by a dynamic bit of SQL/script.
When I run this whether it succeeds or not I see no output from sqlcmd.exe in my console. For user feedback I'd like to pipe this in real time to the console. How could I do that?
Here's how I have done it in the past, it makes use of events from StandardOut and StandardError. As these are executed asynchronously you are not entirely in control of the output (in terms of when it happens), but it should be close to what you need.
$SqlCommandArguments = #()
$SqlCommandArguments += "-S $DbHost"
$SqlCommandArguments += "-d $DbSchema"
$SqlCommandArguments += "-Q `"do some crazy db change here`""
ExecuteProcess -FileName "SqlCmd.exe" -CommandArguments $SqlCommandArguments -Verbose:$VerbosePreference
function ExecuteProcess
{
[cmdletbinding()]
param
(
[string]$FileName,
[string[]]$CommandArguments
)
Write-Verbose "$FileName $CommandArguments"
$startInfo = New-Object System.Diagnostics.ProcessStartInfo
$startInfo.FileName = $FileName
$startInfo.Arguments = $CommandArguments
$startInfo.RedirectStandardError = $true
$startInfo.RedirectStandardOutput = $true
$startInfo.UseShellExecute = $false
$startInfo.CreateNoWindow = $true
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $startInfo
$eventOutputDataReceived = Register-ObjectEvent -InputObject $process -EventName OutputDataReceived -MessageData $VerbosePreference -Action {
if ($($EventArgs.data))
{
Write-Verbose $EventArgs.data -verbose:$event.MessageData
}
}
$global:standardError = New-Object System.Text.StringBuilder
$eventErrorDataReceived = Register-ObjectEvent -InputObject $process -EventName ErrorDataReceived -Action {
if ($($EventArgs.data))
{
$global:standardError.Append("$($EventArgs.data)`r`n")
Write-Warning -message $EventArgs.data
}
}
$process.Start() | Out-Null
$process.BeginOutputReadLine()
$process.BeginErrorReadLine()
$process.WaitForExit()
Unregister-Event -SourceIdentifier $eventOutputDataReceived.Name
Unregister-Event -SourceIdentifier $eventErrorDataReceived.Name
$exitCode = $process.ExitCode
if ($exitCode -ne 0)
{
Write-Error $global:standardError.ToString()
throw "$FileName Failed!"
}
}