Get DNS script has missing output in report - powershell

<#
Gets the various dns record type for a domain or use -RecordType all for all and -Report to file output.
Use like .\get-dnsrecords.ps1 -Name Facebook -RecordType all or .\get-dnsrecords.ps1 -name facebook -RecordType MX
#>
param(
[Parameter(Mandatory = $True,
ValueFromPipelineByPropertyName = $True,
HelpMessage = "Specifies the domain.")]
[string]$Name,
[Parameter(Mandatory = $False,
HelpMessage = "Which Record.")]
[ValidateSet('A', 'MX', 'TXT', 'All')]
[string]$RecordType = 'txt',
[Parameter(Mandatory = $false,
HelpMessage = "DNS Server to use.")]
[string]$Server = '8.8.8.8',
[Parameter(Mandatory = $false,
HelpMessage = "Make a csv report in c:\Reports")]
[Switch]$Report
)
IF ($Name -notlike "*.*") {
$Name = $Name + '.com'
}
If ($Report) {
$filename = [environment]::getfolderpath("mydocuments") + '\' + $($RecordType) + '-' + ($Name.Split('.')[0]) + '.csv'
}
If ($RecordType -eq 'txt' -or $RecordType -eq 'All') {
$TXTRecord = Resolve-DnsName $Name -Type txt -Server $Server -ErrorAction Stop | ForEach-Object {
[PSCustomObject][ordered]#{
name = $_.name
type = $_.Type
ttl = $_.ttl
section = $_.Section
strings = ($_.strings | Out-String).trim()
}
}
If ($RecordType -eq 'txt') {
$TXTRecord
If ($Report) {
$TXTRecord | Export-Csv $filename -NoTypeInformation -Delimiter ','
}
$TXTRecord
Return write-host $filename -ForegroundColor blue
}
}
If ($RecordType -eq 'mx' -or $RecordType -eq 'All' ) {
$MXRecord = Resolve-DnsName $Name -Type mx -Server $Server -ErrorAction Stop | ForEach-Object {
[PSCustomObject]#{
Name = $_.name
Type = $_.type
TTL = $_.ttl
Section = $_.section
NameExchange = $_.nameexchange
}
}
If ($RecordType -eq 'MX') {
If ($Report) {
$MXRecord | Export-Csv $filename -NoTypeInformation
}
$MXRecord
Return Write-Host $filename -ForegroundColor blue
}
}
If ($RecordType -eq 'a' -or $RecordType -eq 'All' ) {
$ARecord = Resolve-DnsName $Name -Type A -Server $Server -ErrorAction Stop | ForEach-Object {
[PSCustomObject]#{
Name = $_.name
Type = $_.type
TTL = $_.ttl
Section = $_.section
IP4Address = $_.IP4Address
}
}
If ($RecordType -eq 'a') {
If ($Report) {
$ARecord | Export-Csv $filename -NoTypeInformation
}
$ARecord
Return write-host $filename -ForegroundColor blue
}
}
If ($Report) {
$TXTRecord | Export-Csv $filename -NoTypeInformation
$MXRecord | Select-Object name, Type, ttyl, section, NameExchange | Export-Csv $filename -NoTypeInformation -Append -Force
$ARecord | Select-Object name, Type, ttyl, section, IP4Address | Export-Csv $filename -NoTypeInformation -Append -Force
}
$TXTRecord
$MXRecord
$ARecord
Return Write-Host $filename -ForegroundColor blue
Running .\get-dnsrecords.ps1 -Name Facebook -RecordType all -Report
Example report Output file is like the following and the host blast is ugly as well.
"name","type","ttl","section","strings"
"Facebook.com","TXT","3600","Answer","String"
"Facebook.com","TXT","3600","Answer","String"
"FaceBook.com","MX","21001","Answer",
"FaceBook.com","MX","21001","Answer",
"FaceBook.com","A","20","Answer",
Mx is missing NameExchange
A record is missing IP4Address
Ideas on how to make the report output include the missing items and bonus how to make the host output more readable ?
The problem is when I try to combine the output variables at the end and then export to file. I am just not sure how to correct it.

Here is what I did. If someone has a better answer please let me know.
Running .\get-dnsrecords.ps1 -Name Facebook -RecordType all -Report
The key lines are as follows.
$final = $TXTRecord | ForEach-Object {
[PSCustomObject]#{
Name = $_.name
Type = $_.type
TTL = $_.ttl
Section = $_.section
strings = $_.strings
NameExchange = $_.nameexchange
IP4Address = $_.IP4Address
}
}
$final += $MXRecord | ForEach-Object {
[PSCustomObject]#{
Name = $_.name
Type = $_.type
TTL = $_.ttl
Section = $_.section
strings = $_.strings
NameExchange = $_.nameexchange
IP4Address = $_.IP4Address
}
}
$final += $ARecord | ForEach-Object {
[PSCustomObject]#{
Name = $_.name
Type = $_.type
TTL = $_.ttl
Section = $_.section
strings = $_.strings
NameExchange = $_.nameexchange
IP4Address = $_.IP4Address
}
}
$final | Export-Csv $filename -NoTypeInformation
Full code below
<#
Gets the various dns record type for a domain or use -RecordType all for all and -Report to file output.
Use like .\get-dnsrecords.ps1 -Name Facebook -RecordType all or .\get-dnsrecords.ps1 -name facebook -RecordType MX
#>
param(
[Parameter(Mandatory = $True,
ValueFromPipelineByPropertyName = $True,
HelpMessage = "Specifies the domain.")]
[string]$Name,
[Parameter(Mandatory = $False,
HelpMessage = "Which Record.")]
[ValidateSet('A', 'MX', 'TXT', 'All')]
[string]$RecordType = 'all',
[Parameter(Mandatory = $false,
HelpMessage = "DNS Server to use.")]
[string]$Server = '8.8.8.8',
[Parameter(Mandatory = $false,
HelpMessage = "Make a csv report in c:\Reports")]
[Switch]$Report
)
IF ($Name -notlike "*.*") {
$Name = $Name + '.com'
}
If ($Report) {
$filename = [environment]::getfolderpath("mydocuments") + '\' + $($RecordType) + '-' + ($Name.Split('.')[0]) + '.csv'
}
If ($RecordType -eq 'txt' -or $RecordType -eq 'All') {
$TXTRecord = Resolve-DnsName $Name -Type txt -Server $Server -ErrorAction Stop | ForEach-Object {
[PSCustomObject][ordered]#{
name = $_.name
type = $_.Type
ttl = $_.ttl
section = $_.Section
strings = ($_.strings | Out-String).trim()
}
}
If ($RecordType -eq 'txt') {
$TXTRecord
If ($Report) {
$TXTRecord | Export-Csv $filename -NoTypeInformation -Delimiter ','
}
$TXTRecord
Return write-host $filename -ForegroundColor blue
}
}
If ($RecordType -eq 'mx' -or $RecordType -eq 'All' ) {
$MXRecord = Resolve-DnsName $Name -Type mx -Server $Server -ErrorAction Stop | ForEach-Object {
[PSCustomObject]#{
Name = $_.name
Type = $_.type
TTL = $_.ttl
Section = $_.section
NameExchange = $_.nameexchange
}
}
If ($RecordType -eq 'MX') {
If ($Report) {
$MXRecord | Export-Csv $filename -NoTypeInformation
}
$MXRecord
Return Write-Host $filename -ForegroundColor blue
}
}
If ($RecordType -eq 'a' -or $RecordType -eq 'All' ) {
$ARecord = Resolve-DnsName $Name -Type A -Server $Server -ErrorAction Stop | ForEach-Object {
[PSCustomObject]#{
Name = $_.name
Type = $_.type
TTL = $_.ttl
Section = $_.section
IP4Address = $_.IP4Address
}
}
If ($RecordType -eq 'a') {
If ($Report) {
$ARecord | Export-Csv $filename -NoTypeInformation
}
$ARecord
Return write-host $filename -ForegroundColor blue
}
}
If ($Report) {
$final = $TXTRecord | ForEach-Object {
[PSCustomObject]#{
Name = $_.name
Type = $_.type
TTL = $_.ttl
Section = $_.section
strings = $_.strings
NameExchange = $_.nameexchange
IP4Address = $_.IP4Address
}
}
$final += $MXRecord | ForEach-Object {
[PSCustomObject]#{
Name = $_.name
Type = $_.type
TTL = $_.ttl
Section = $_.section
strings = $_.strings
NameExchange = $_.nameexchange
IP4Address = $_.IP4Address
}
}
$final += $ARecord | ForEach-Object {
[PSCustomObject]#{
Name = $_.name
Type = $_.type
TTL = $_.ttl
Section = $_.section
strings = $_.strings
NameExchange = $_.nameexchange
IP4Address = $_.IP4Address
}
}
$final | Export-Csv $filename -NoTypeInformation
}
$TXTRecord
$MXRecord
$ARecord
Return Write-Host $filename -ForegroundColor blue

Related

How can I log these Active Directory account operations to a CSV file?

I want to create a .csv file for each AD account that is disabled and moved that has the $account.Distingushed name of the object move and the $OU.Distinguished name that the object is moved from.
What would be the best way to handle this?
$OUs | Where-Object{$excludeOUS -notcontains $_.DistinguishedName } | Foreach-Object {
$params = #{}
$params = #{
SearchBase = [String]$_.DistinguishedName
SearchScope = [String]"OneLevel"
AccountInactive = $true
TimeSpan = ([timespan]$days)
Verbose = $true
}
If($users) {
$params.Add("UsersOnly",$true)
}
ElseIf($computers) {
$params.Add("ComputersOnly",$true)
}
$accounts = Search-ADAccount #params
foreach ($account in $accounts) {
$params = #{}
$params = #{
Identity = [string]$account.DistinguishedName
Verbose = $true
}
If ($noDisable -notcontains $account.Name -and $account.ObjectClass -eq "User" ) {
Disable-ADAccount #params #whatIf
$params.Add("Description",$description)
Set-ADUser #params #WhatIf
$params.Remove('Description')
$params.Add("TargetPath", 'OU=Disabled Users,DC=test,DC=local')
Move-ADObject #params #WhatIf
# Somehow Export $account.DistinghuisedName and $OU.Distinguished name to .csv???
}
ElseIf ($noDisable -notcontains $account.Name -and $account.ObjectClass -eq "Computer") {
Disable-ADAccount #params #whatIf
$params.Add("Description",$description)
Set-ADComputer #params #WhatIf
$params.Remove('Description')
$params.Add("TargetPath", 'OU=Disabled Computers,DC=test,DC=local')
Move-ADObject #params #WhatIf
# Somehow Export $account.DistinghuisedName and $OU.Distinguished name to .csv???
}
}
}
You can try something like below code (untested).
Set the variables for the csvPath, ouDistinguishedName and accountDistinguishedName.
You can add those vars to an object and export to csv. I used $account.Name as the csv name, but you can use something else.
$csvPath = "c:\temp"
$OUs | Where-Object { $excludeOUS -notcontains $_.DistinguishedName } | Foreach-Object {
$ouDistinguishedName = $_.DistinguishedName
$params = #{ }
$params = #{
SearchBase = [String]$_.DistinguishedName
SearchScope = [String]"OneLevel"
AccountInactive = $true
TimeSpan = ([timespan]$days)
Verbose = $true
}
If ($users) {
$params.Add("UsersOnly", $true)
}
ElseIf ($computers) {
$params.Add("ComputersOnly", $true)
}
$accounts = Search-ADAccount #params
foreach ($account in $accounts) {
$accountDistinguishedName = $account.DistinguishedName
$accountName = $account.Name
$params = #{ }
$params = #{
Identity = [string]$account.DistinguishedName
Verbose = $true
}
If ($noDisable -notcontains $account.Name -and $account.ObjectClass -eq "User" ) {
Disable-ADAccount #params #whatIf
$params.Add("Description", $description)
Set-ADUser #params #WhatIf
$params.Remove('Description')
$params.Add("TargetPath", 'OU=Disabled Users,DC=test,DC=local')
Move-ADObject #params #WhatIf
# Somehow Export $account.DistinghuisedName and $OU.Distinguished name to .csv???
$objectProperty = #{}
$objectProperty.Add('Account',$accountDistinguishedName)
$objectProperty.Add('OU',$ouDistinguishedName)
$object = New-Object -TypeName psobject -Property $objectProperty
$object | Export-Csv "$csvPath\$accountName.csv" -NoTypeInformation
}
ElseIf ($noDisable -notcontains $account.Name -and $account.ObjectClass -eq "Computer") {
Disable-ADAccount #params #whatIf
$params.Add("Description", $description)
Set-ADComputer #params #WhatIf
$params.Remove('Description')
$params.Add("TargetPath", 'OU=Disabled Computers,DC=test,DC=local')
Move-ADObject #params #WhatIf
# Somehow Export $account.DistinghuisedName and $OU.Distinguished name to .csv???
$objectProperty = #{}
$objectProperty.Add('Account',$accountDistinguishedName)
$objectProperty.Add('OU',$ouDistinguishedName)
$object = New-Object -TypeName psobject -Property $objectProperty
$object | Export-Csv "$csvPath\$accountName.csv" -NoTypeInformation
}
}
}
You can even export this straightly as a hashtable:
#{"Account" = $accountDistinguishedName; "OU" = $ouDistinguishedName}.GetEnumerator() | Export-Csv "$($csvpath)\$($accountname)" -NoTypeInformation
I figured it out!
$acctsCSV = #(
[pscustomobject]#{
Account = [string]$account.Name
OU = [string]$OU.DistinguishedName
}
)
$acctsCSV | Export-Csv -Path $filePath -NoTypeInformation

Getting unassigned phone numbers for Skype for Business in powershell

Has anyone ever done something like this in powershell? I'm automating new user creation and have to set up their skype for business accounts. Here's what I have so far:
<# set up skype for business #>
Enable-CsUser -Identity $FULLNAME `
-RegistrarPool REDACTED
-SipAddress $SIP
Set-CsUser $FULLNAME `
-EnterpriseVoiceEnabled $true `
-ExchangeArchivingPolicy Uninitialized `
-LineURI $PHONENUMBER
# only for driver manager/managers
Grant-CsConferencingPolicy $FULLNAME `
-PolicyName $ConferencingPolicy
Grant-CsExternalAccessPolicy -identity $FULLNAME `
-PolicyName 'Allow external access'
All I have left is the to assign the LineURI, and I can't seem to find anything about how to do that. I did, however, find a script that does this, but it doesn't seem like it's specific to my needs. My question is this: how can I query Skype for Business in powershell to grab the first unassigned number and assign it as the LineURI? I have been using New-CSUnassignedNumber but cannot seem to make any headway.
SfB doesn't keep a record of your number ranges, so it doesn't know if you assigning 1299 is the last in a range, or if the range stretches into the 1300's
Get-CsUser | ? LineUri | Select LineUri | Sort
this will give you a sorted list of all assigned uri's in your organization, so you'll be able to pick out ones which may be assignable, regardless you can use a number of methods to find what you're looking for, but you may be interested in this for the longer-term approach, it's a script which takes in your number ranges, and outputs a list of the used and available ones in a nice Csv.
#region Input
$NumRangeKeyTable = #{
#Make sure numbers are in the same format as they are in Skype,
#Do not include any ';ext' or 'tel:' etc. formatting!
#Put single numbers in the format:
# "+35313456789" = ""
#Put number ranges in the format:
# "+35313456700" = "+35313456799"
"+35313456789" = ""
"+35313456700" = "+35313456799"
}
#Save Location, set to $null to be prompted for location.
$FileName = $null
#endregion
#region Code
#region Helper Functions
Function Get-CsAssignedURIs {
$AllNumbers = #()
$Users = Get-CsUser
$Users | ? {$_.LineURI -ne ""} | %{ $AllNumbers += New-Object PSObject -Property #{Name = $_.DisplayName ; SipAddress = $_.SipAddress ; Number = $_.LineURI ; Type = "User" }}
$Users | ? {$_.PrivateLine -ne ""} | %{ $AllNumbers += New-Object PSObject -Property #{Name = $_.DisplayName ; SipAddress = $_.SipAddress ; Number = $_.PrivateLine ; Type = "PrivateLine" }}
Get-CsRgsWorkflow | Where-Object {$_.LineURI -ne ""} | Select Name,LineURI | %{$AllNumbers += New-Object PSObject -Property #{Name = $_.Name ; SipAddress = $_.PrimaryUri ; Number = $_.LineURI ; Type = "Workflow" }}
Get-CsCommonAreaPhone -Filter {LineURI -ne $null} | %{ $AllNumbers += New-Object PSObject -Property #{Name = $_.DisplayName ; SipAddress = $_.SipAddress ; Number = $_.LineURI ; Type = "CommonArea" }}
Get-CsAnalogDevice -Filter {LineURI -ne $null} | %{ $AllNumbers += New-Object PSObject -Property #{Name = $_.DisplayName ; SipAddress = $_.SipAddress ; Number = $_.LineURI ; Type = "AnalogDevice" }}
Get-CsExUmContact -Filter {LineURI -ne $null} | %{ $AllNumbers += New-Object PSObject -Property #{Name = $_.DisplayName ; SipAddress = $_.SipAddress ; Number = $_.LineURI ; Type = "ExUmContact" }}
Get-CsDialInConferencingAccessNumber -Filter {LineURI -ne $null} | %{ $AllNumbers += New-Object PSObject -Property #{Name = $_.DisplayName ; SipAddress = $_.PrimaryUri ; Number = $_.LineURI ; Type = "DialInAccess" }}
Get-CsTrustedApplicationEndpoint -Filter {LineURI -ne $null} | %{ $AllNumbers += New-Object PSObject -Property #{Name = $_.DisplayName ; SipAddress = $_.SipAddress ; Number = $_.LineURI ; Type = "ApplicationEndpoint" }}
Return $AllNumbers
}
function Get-UniqueExt {
Param(
[string]$Uri1,
[string]$Uri2
)
$Reg = "^([0-9+])+$"
if ([string]::IsNullOrEmpty($uri1) -and [string]::IsNullOrEmpty($Uri2)) { return "Two blank strings provided" }
if ($Uri1 -eq $Uri2) { return $Uri1 }
if ([string]::IsNullOrEmpty($uri1)) { return $Uri2 }
if ([string]::IsNullOrEmpty($uri2)) { return $Uri1 }
if ($Uri1.Length -ne $Uri2.Length) { return "Strings cannot be different lengths" }
if (($Uri1 -notmatch $Reg) -or ($Uri2 -notmatch $Reg)) { return "Strings must be in the format '0123..' or '+123..'" }
($Uri1.Length-1)..0 | % {
if ($Uri1[$_] -ne $Uri2[$_]) { $Diff = $_ }
}
$Start = $Uri1.Substring(0,$Diff)
$Sub1 = $Uri2.Substring($Diff)
$Sub2 = $Uri1.Substring($Diff)
if ($Sub1 -lt $Sub2) {
$Min = $Sub1 ; $Max = $Sub2
} else {
$Min = $Sub2 ; $Max = $Sub1
}
$FormatStr = "" ; 1..$Min.Length | % { $FormatStr += "0"}
$Min..$Max | % { "$($Start)$($_.ToString($FormatStr))" }
}
function Save-ToFile {
Param(
[Parameter(ValueFromPipeline=$True)]
$Item = $null,
[switch]$ReturnName,
$ExtFilter = "*",
$WinTitle = "Select File",
$FileTypeDisplay = $null
)
If ($FileTypeDisplay -eq $null) {
If ($ExtFilter -eq "*") {
$ExtName = "All"
} Else {
$ExtName = (Get-Culture).TextInfo.ToTitleCase($ExtFilter)
}} Else {
$ExtName = (Get-Culture).TextInfo.ToTitleCase($FileTypeDisplay) }
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$FolderDialog = New-Object System.Windows.Forms.SaveFileDialog
$FolderDialog.Filter = "$($ExtName) files (*.$($ExtFilter.ToLowerInvariant()))| *.$($ExtFilter.ToLowerInvariant())"
$FolderDialog.Title = $WinTitle
$Result = $FolderDialog.ShowDialog()
If ($Result -eq "OK"){
$Item | Out-File $FolderDialog.FileName -Append
If ($ReturnName) { return $FolderDialog.FileName }}
Else {
Write-Error "No file selected" }
}
#endregion
Function Main {
Param ( [Hashtable]$NumRanges )
#region Process Data
$AllNums = $NumRanges.Keys | % {
Get-UniqueExt -Uri1 $_ -Uri2 $NumRanges[$_]
}
$S4BNums = Get-CsAssignedURIs
$S4BNums | % { $_.Number = ($_.Number.Split(';')[0] -ireplace "tel:","") }
$KT = #{}
$S4BNums | % {
$KT[$_.Number] = $_
}
$FullRecord = $AllNums | Sort | % {
$Number = $_
$Type = ""
$Name = ""
if ($KT[$_] -ne $null){
$UseDetails = $KT[$_]
$Name = $UseDetails.Name
$Type = $UseDetails.Type
}
[PSCustomObject]#{
Number = $Number
Name = $Name
Type = $Type
}
}
#endregion
return $FullRecord
}
$Results = Main $NumRangeKeyTable
#region Output-Data
if ($FileName -eq $null) {
$FileName = (Save-ToFile -Item "" -ReturnName -ExtFilter "Csv")
}
if ($FileName -ne $null) {
$Results | Export-Csv -Path $FileName -NoTypeInformation
} else { $Results | Out-GridView }
#endregion
#endregion

Issues with powershell invoke-command, Unexpected token '-ArgumentList' in expression or statement

I am quite new to powershell. I am trying to remote to PCs in a csv file and extract the status of a registry key. However I get the error
"Unexpected token '-ArgumentList' in expression or statement." when I try to execute. And I am not pretty sure on the syntax of the Invoke-Command, can one of your pls verify if it is correct? Appreciate your help.
So basically, what I intend to do is, get computer names, specify an output path which I will be then using inside the invoke command. Testing the online status of the PC, checking the required registry value and writing it to the file.
$computers = Get-Content "C:\Temp\AutoSug\Computers.txt"
$output_path = "C:\Temp\AutoSug\output.csv"
foreach($computer in $computers)
{
Test-Connection -computername $computer -Quiet
If (Test-Connection $computer -count 1 -quiet)
{
Invoke-Command -computer $computer -ScriptBlock
{
param(
$output_path
)
$hostname = (Get-CIMInstance CIM_ComputerSystem).Name
$objExcel = New-Object -ComObject Excel.Application
if ($objExcel.Version -eq "15.0")
{
$HKEY_USERS = Get-ChildItem REGISTRY::HKEY_USERS | where-object { ($_.Name -like "*S-1-5-21*") -and ($_.Name -notlike "*_Classes") }
$Users = #()
$value = #()
foreach ($User in $HKEY_USERS)
{
$PROFILESID = Get-ChildItem REGISTRY::"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" | Where-Object { $_.name -like "*" + $USER.PSChildName + "*" }
$SID = $PROFILESID.PSChildName
foreach ($value in $SID)
{
$key = Get-Item REGISTRY::HKEY_USERS\$VALUE\Software\Microsoft\Office\15.0\Outlook\Preferences -ErrorAction SilentlyContinue
$gold = $key.property
if($gold -like 'ShowAutoSug')
{
$grail = (Get-ItemProperty REGISTRY::HKEY_USERS\$VALUE\Software\Microsoft\Office\15.0\Outlook\Preferences).ShowAutoSug
$objSID = New-Object System.Security.Principal.SecurityIdentifier($value)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$hostname, $objUser, $value , $grail | Add-Content $output_path
}
else
{
$objSID = New-Object System.Security.Principal.SecurityIdentifier($value)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$hostname,$objUser, $value , "The Auto Complete is not disabled" | Add-Content $output_path
}
}
}
}
if ($objExcel.Version -eq "14.0")
{
$HKEY_USERS = Get-ChildItem REGISTRY::HKEY_USERS | where-object { ($_.Name -like "*S-1-5-21*") -and ($_.Name -notlike "*_Classes") }
$Users = #()
$value = #()
foreach ($User in $HKEY_USERS)
{
$PROFILESID = Get-ChildItem REGISTRY::"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" | Where-Object { $_.name -like "*" + $USER.PSChildName + "*" }
$SID = $PROFILESID.PSChildName
foreach ($value in $SID)
{
$key = Get-Item REGISTRY::HKEY_USERS\$VALUE\Software\Microsoft\Office\14.0\Outlook\Preferences -ErrorAction SilentlyContinue
$gold = $key.property
if($gold -like 'ShowAutoSug')
{
$grail = (Get-ItemProperty REGISTRY::HKEY_USERS\$VALUE\Software\Microsoft\Office\14.0\Outlook\Preferences).ShowAutoSug
$objSID = New-Object System.Security.Principal.SecurityIdentifier($value)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$hostname, $objUser, $value , $grail | Add-Content -path $output_path
}
else
{
$objSID = New-Object System.Security.Principal.SecurityIdentifier($value)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$hostname,$objUser, $value , "The Auto Complete is not disabled" | Add-Content $output_path
}
}
}
}
if ($objExcel.Version -eq "12.0")
{
$HKEY_USERS = Get-ChildItem REGISTRY::HKEY_USERS | where-object { ($_.Name -like "*S-1-5-21*") -and ($_.Name -notlike "*_Classes") }
$Users = #()
$value = #()
foreach ($User in $HKEY_USERS)
{
$PROFILESID = Get-ChildItem REGISTRY::"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" | Where-Object { $_.name -like "*" + $USER.PSChildName + "*" }
$SID = $PROFILESID.PSChildName
foreach ($value in $SID)
{
$key = Get-Item REGISTRY::HKEY_USERS\$VALUE\Software\Microsoft\Office\12.0\Outlook\Preferences -ErrorAction SilentlyContinue
$gold = $key.property
if($gold -like 'ShowAutoSug')
{
$grail = (Get-ItemProperty REGISTRY::HKEY_USERS\$VALUE\Software\Microsoft\Office\12.0\Outlook\Preferences).ShowAutoSug
$objSID = New-Object System.Security.Principal.SecurityIdentifier($value)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$hostname, $objUser, $value , $grail | Add-Content $output_path
}
else
{
$objSID = New-Object System.Security.Principal.SecurityIdentifier($value)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$hostname,$objUser, $value , "The Auto Complete is not disabled" |Add-Content $output_path
}
}
}
}
} -ArgumentList $output_path
}
else
{
$status = 'Offline'
$computer , $status | Add-Content $output_path
}
}
To fix your error, simply cut -ArgumentList $output_path and put it before -ScriptBlock like:
Invoke-Command -computer $computer -ArgumentList $output_path -ScriptBlock ....

Alternative to Append export-csv powershell

I add user logon and logout tracking script
I found that some computers do not export csv as they have powershell 2.0 because append is not supported is there any alternative?
$ErrorActionPreference = 'Continue'
####**** Tracking user logon *****#####
$username = $env:USERNAME
$computername = $env:COMPUTERNAME
$ipv4 = Test-Connection -ComputerName (hostname) -Count 1 | foreach { $_.ipv4address }
$ipv6 = Test-Connection -ComputerName (hostname) -Count 1 | foreach { $_.ipv6address }
$timeformat='MM-dd-yyyy hh:mm:ss tt'
$time = (Get-Date).ToString($timeformat)
$action = 'Logon'
$filedate = 'MM-dd-yyyy'
$filename = 'CompInfo' + ' ' + $(Get-Date).ToString($filedate)
#Creates custom table and sorts the information
$table= New-Object –TypeName PSObject -Property #{
'Date/Time' = $time
'Username' = $username
'ComputerName'= $computername
'IPv4 Address' = $ipv4
'IPv6 Address' = $ipv6
'Notes/Action' = $action
} | Select date/time, username, computername, 'IPv4 Address', 'IPv6 Address', notes/action
$table | Export-Csv "d:\$env:username.csv" -NoClobber -append -NoTypeInformation
Try this
#Thanks to Dmitry Sotnikov
#https://dmitrysotnikov.wordpress.com/2010/01/19/export-csv-append/
#### Append CSV Powershell 2.0
function Export-CSV {
[CmdletBinding(DefaultParameterSetName='Delimiter',
SupportsShouldProcess=$true, ConfirmImpact='Medium')]
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[System.Management.Automation.PSObject]
${InputObject},
[Parameter(Mandatory=$true, Position=0)]
[Alias('PSPath')]
[System.String]
${Path},
#region -Append (added by Dmitry Sotnikov)
[Switch]
${Append},
#endregion
[Switch]
${Force},
[Switch]
${NoClobber},
[ValidateSet('Unicode','UTF7','UTF8','ASCII','UTF32',
'BigEndianUnicode','Default','OEM')]
[System.String]
${Encoding},
[Parameter(ParameterSetName='Delimiter', Position=1)]
[ValidateNotNull()]
[System.Char]
${Delimiter},
[Parameter(ParameterSetName='UseCulture')]
[Switch]
${UseCulture},
[Alias('NTI')]
[Switch]
${NoTypeInformation})
begin
{
# This variable will tell us whether we actually need to append
# to existing file
$AppendMode = $false
try {
$outBuffer = $null
if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
{
$PSBoundParameters['OutBuffer'] = 1
}
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Export-Csv',
[System.Management.Automation.CommandTypes]::Cmdlet)
#String variable to become the target command line
$scriptCmdPipeline = ''
# Add new parameter handling
#region Dmitry: Process and remove the Append parameter if it is present
if ($Append) {
$PSBoundParameters.Remove('Append') | Out-Null
if ($Path) {
if (Test-Path $Path) {
# Need to construct new command line
$AppendMode = $true
if ($Encoding.Length -eq 0) {
# ASCII is default encoding for Export-CSV
$Encoding = 'ASCII'
}
# For Append we use ConvertTo-CSV instead of Export
$scriptCmdPipeline += 'ConvertTo-Csv -NoTypeInformation '
# Inherit other CSV convertion parameters
if ( $UseCulture ) {
$scriptCmdPipeline += ' -UseCulture '
}
if ( $Delimiter ) {
$scriptCmdPipeline += " -Delimiter '$Delimiter' "
}
# Skip the first line (the one with the property names)
$scriptCmdPipeline += ' | Foreach-Object {$start=$true}'
$scriptCmdPipeline += '{if ($start) {$start=$false} else {$_}} '
# Add file output
$scriptCmdPipeline += " | Out-File -FilePath '$Path'"
$scriptCmdPipeline += " -Encoding '$Encoding' -Append "
if ($Force) {
$scriptCmdPipeline += ' -Force'
}
if ($NoClobber) {
$scriptCmdPipeline += ' -NoClobber'
}
}
}
}
$scriptCmd = {& $wrappedCmd #PSBoundParameters }
if ( $AppendMode ) {
# redefine command line
$scriptCmd = $ExecutionContext.InvokeCommand.NewScriptBlock(
$scriptCmdPipeline
)
} else {
# execute Export-CSV as we got it because
# either -Append is missing or file does not exist
$scriptCmd = $ExecutionContext.InvokeCommand.NewScriptBlock(
[string]$scriptCmd
)
}
# standard pipeline initialization
$steppablePipeline = $scriptCmd.GetSteppablePipeline(
$myInvocation.CommandOrigin)
$steppablePipeline.Begin($PSCmdlet)
} catch {
throw
}
}
process
{
try {
$steppablePipeline.Process($_)
} catch {
throw
}
}
end
{
try {
$steppablePipeline.End()
} catch {
throw
}
}
}
#### Append CSV Powershell 2.0
$ErrorActionPreference = 'Continue'
####**** Tracking user logon *****#####
$username = $env:USERNAME
$computername = $env:COMPUTERNAME
$ipv4 = Test-Connection -ComputerName (hostname) -Count 1 | foreach { $_.ipv4address }
$ipv6 = Test-Connection -ComputerName (hostname) -Count 1 | foreach { $_.ipv6address }
$timeformat='MM-dd-yyyy hh:mm:ss tt'
$time = (Get-Date).ToString($timeformat)
$action = 'Logon'
$filedate = 'MM-dd-yyyy'
$filename = 'CompInfo' + ' ' + $(Get-Date).ToString($filedate)
#Creates custom table and sorts the information
$table= New-Object –TypeName PSObject -Property #{
'Date/Time' = $time
'Username' = $username
'ComputerName'= $computername
'IPv4 Address' = $ipv4
'IPv6 Address' = $ipv6
'Notes/Action' = $action
} | Select date/time, username, computername, 'IPv4 Address', 'IPv6 Address', notes/action
$table | Export-Csv "D:\$env:username.csv" -NoClobber -Append -Delimiter ',' -NoTypeInformation

Export table to file twice due to incorrect format

I'm using this code:
Function Main
{
$domain = "LDAP://www.example.com"
$outfile = 'C:\Scripts\Tests\usersDump.csv'
$properties = "SamAccountName", "lastLogonTimestamp", "AccountExpires", "FirstName", "LastName", "distinguishedName", "employeeNumber", "employeeID", "description", "extensionattribute8", "userAccountControl"
Write-Host "Searching AD..."
$dn = New-Object System.DirectoryServices.DirectoryEntry($domain)
$ds = New-Object System.DirectoryServices.DirectorySearcher($dn)
$ds.Filter = '(&(objectCategory=User)(samAccountType:1.2.840.113556.1.4.803:=805306368))'
$ds.PageSize=1000
$ds.PropertiesToLoad.AddRange($properties)
$list = $ds.FindAll()
Write-Host "Complete"
# The AD results are converted to an array of hashtables.
Write-Host "Exporting User Attributes to table..."
$table = #()
$garbageCounter = 0
foreach($item in $list) {
$hash = #{}
foreach($name in $properties){
if ($item.Properties[$name]) {
$hash.$name = $item.Properties[$name][0]
} else {
$hash.$name = $null
}
}
$table += New-Object PSObject -Property $hash
$garbageCounter++
if ($garbageCounter -eq 1000)
{
[System.GC]::Collect()
$garbageCounter = 0
}
}
[System.GC]::Collect()
Write-Host "Complete."
$listOfBadDateValues = '9223372036854775807', '9223372036854770000', '0'
$maxDateValue = '12/31/1600 5:00 PM'
Write-Host "fixing table values for `"lastLogonTimestamp`" and `"AccountExpires`""
$tableFixedValues = $table | % {
if ($_.lastLogonTimestamp) {
$_.lastLogonTimestamp = ([datetime]::FromFileTime($_.lastLogonTimestamp)).ToString('g')
}; if (($_.AccountExpires) -and ($listOfBadDateValues -contains $_.AccountExpires)) {
$_.AccountExpires = $null
} else {
if (([datetime]::FromFileTime($_.AccountExpires)).ToString('g') -eq $maxDateValue) {
$_.AccountExpires = $null
} Else {
$_.AccountExpires = ([datetime]::FromFileTime($_.AccountExpires)).ToString('g')
}
};$_}
Write-Host "Complete"
Write-Host "Exporting table to csv file $outfile"
$tableFixedValues | Export-Csv $outfile –encoding "unicode" -NoTypeInformation -Force
Write-Host "Complete"
Write-Host "Done."
}
Main
The problem is the file is written so everything is in 1 column. In order to make the properties in their own column, I use this code...
Write-Host "Converting $outfile to csv file $OutputResultsFile"
$outFileFixed = 'C:\Scripts\Tests\usersDumpFixed.csv'
Import-Csv $outfile | Export-Csv $outFileFixed -NoTypeInformation -Force
Write-Host "Complete"
Is there a way I can do this Without having to open-close it again?
Remove the -Encoding Unicode Parameter from the Export-csv then it will not be in one column