<#
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
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
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
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 ....
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
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