SHIMSOFT-iTunesSearch.psm1
function Get-iTunesAppInfo { <# .SYNOPSIS Apple App Store / Apple Mac App Store のアプリ情報を検索します。 .DESCRIPTION Apple App Store / Apple Mac App Store のアプリ情報を検索します。 MDM などでアプリの制御に利用する BundleID を比較的容易に確認できます。 .EXAMPLE Get-iTunesAppInfo -Term Pages -Platform iPhone "Pages" を AppName に含む「iPhone」用アプリ情報を情報を列挙します。 .EXAMPLE Get-iTunesAppInfo -Term Pages -Platform Mac "Pages" を AppName に含むの「Mac」用アプリ情報を情報を列挙します。 .EXAMPLE Get-iTunesAppInfo -Term "Microsoft Word" "Microsoft Word" を AppName に含むの「iPhone」「iPad」用アプリ情報を情報を列挙します。 .EXAMPLE Get-iTunesAppInfo -Term "Microsoft Word" -FilterMode Equal FilterMode オプションで Equal を指定すると Term に指定した文字列と一致する情報となるようにフィルターします。 .EXAMPLE Get-iTunesAppInfo -Term 361285480 -AppID 確認したいアプリの ID が判明している場合、Term オプションに ID を指定し、 -AppID オプションを指定することで アプリ情報を確認できます。 .EXAMPLE Get-iTunesAppInfo -Term "361285480,361309726,361304891" -AppID 確認したいアプリの ID が複数ある場合、カンマ区切りで文字列指定し、 -AppID オプションを指定することで 一括でアプリ情報を確認できます。 .EXAMPLE Get-iTunesAppInfo -Term apple -Developer "apple" を ArtistName に含むの「iPhone」「iPad」用アプリ情報を情報を列挙します。 .EXAMPLE Get-iTunesAppInfo -Term com.apple.mobileme.fmf1 -BundleID "com.apple.mobileme.fmf1" という BundleID のアプリ情報を情報を列挙します。 .EXAMPLE Get-iTunesAppInfo -Term "com.apple.mobileme.fmf1,com.apple.MobileAddressBook" -BundleID 確認したいアプリの BundleID が複数ある場合、カンマ区切りで文字列指定し -BundleID オプションを指定することで 一括でアプリ情報を確認できます。 .PARAMETER Term 検索するキーワードを指定します。スペースを含む場合は "Microsoft Word" の様にします。 .PARAMETER Platform アプリの対象プラットフォームを指定します。 iPhone : iPhone 用アプリ iPad : iPad 用アプリ Mac : Mac 用アプリ iPhone+iPad : iPhone / iPad 用アプリ混合 All : iPhone / iPad / Mac 用アプリ混合 デフォルト値は "iPhone+iPad" .PARAMETER Country AppSotre の国コードを指定します。デフォルト値は "jp" です。 .PARAMETER AppID App の URL などから ID 情報が判明している場合、ID を指定して検索することができます。 .PARAMETER Developer Term に指定したキーワードが開発者名である場合、このオプションを指定することでよりある程度フィルタして結果を出すことができます。 .PARAMETER BundleID Term に指定したキーワードが BundleID ある場合、このオプションを指定することでよりある程度フィルタして結果を出すことができます。 .PARAMETER FilterMode None, Equal, Like のいずれかを指定します。デフォルト値は Like です。 検索結果が Term にどれほど近いかをフィルタする方式が変ります。 FilterMode 未指定の時に、目的のものが見つからない場合は、None を指定してみてください。 アプリ名が正確にわかっている場合は Equal を指定することでより発見しやすくなります。 .LINK .NOTES .INPUTS パイプラインからの入力可能です。 .OUTPUTS 文字列 #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification="Always multiple results.")] param( [Parameter(Mandatory=$True,Position=1)] [String]$Term, [Parameter(Mandatory=$false,Position=2)] [ValidateSet("iPhone","iPad","iPhone+iPad","Watch","Mac","AppleTV","All")] [String]$Platform="iPhone+iPad", [Parameter(Mandatory=$false,Position=3)] [String]$Country="jp", [Parameter(Mandatory=$false,Position=4)] [Switch]$AppID=$false, [Parameter(Mandatory=$false,Position=5)] [Switch]$Developer=$false, [Parameter(Mandatory=$false,Position=6)] [Switch]$BundleID=$false, [Parameter(Mandatory=$false,Position=7)] [ValidateSet("None","Like","Equal")] [String]$FilterMode="Like", [Parameter(Mandatory=$false,Position=8)] [Switch]$DeveloperID=$false ) $iTunesSearchURL ="https://itunes.apple.com/search?" $iTunesLookupURL ="https://itunes.apple.com/lookup?" $WebClient = New-Object System.Net.WebClient $WebClient.Encoding = [System.Text.Encoding]::UTF8 Write-Verbose ("Term = '{0}', Platform = '{1}', Country = {2}, AppID : {3}, Developer : {4}, BundleID : {5}, Equal : {6}, DeviceID : {7}, Expand {8} " -f $Term, $Platform, $Country, $AppID,$Developer,$BundleID,$Equal,$DeviceID, $Expand) $is_iPhone = $false $is_iPad = $false $is_Mac = $false $is_Watch = $false $is_AppleTV = $false switch ($Platform) { "iPhone" { $is_iPhone = $true } "iPad" { $is_iPad = $true } "iPhone+iPad" { $is_iPhone = $true $is_iPad = $true } "Watch" { $is_Watch = $true } "Mac" { $is_Mac = $true } "AppleTV" { $is_AppleTV = $true } "All" { $is_iPhone = $true $is_iPad = $true $is_Mac = $true $is_Watch = $true $is_AppleTV = $true } } $AppInfo = @() $is_Finished = $false if ($AppId) { Write-Verbose ("AppID mode") $URL = ('{0}id={1}&country={2}' -f $iTunesLookupURL, $Term, $Country) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Result = @($SearchResult.Results) if ($null -ne $Result) { $AppInfo += Summary-AppInfo -Results $Result } Write-Output ($AppInfo | Sort-Object -Property AppName) $is_Finished = $ttrue } if ($BundleId) { Write-Verbose ("BundleID mode") $URL = ('{0}bundleId={1}&country={2}' -f $iTunesLookupURL, $Term, $Country) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Result = @($SearchResult.Results) if ($null -ne $Result) { $AppInfo += Summary-AppInfo -Results $Result } Write-Output ($AppInfo | Sort-Object -Property AppName) $is_Finished = $ttrue } if ($DeveloperId) { Write-Verbose ("DeveloperID mode") $offset=0 $Result = @() $All = $false While ($false -eq $All) { $URL = ('{0}id={1}&country={2}&entity=software&limit=200&offset={3}' -f $iTunesLookupURL, $Term, $Country, $offset) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Work = @($SearchResult.Results | Where-Object {$_.wrapperType -eq "software"}) $Result += $Work if ($Work.Count -ge 200) {$offset += 200;Write-Verbose ("`tOffset Loop:{0}" -f $offset); } else { $All = $true} } $AppInfo += Summary-AppInfo -Results $Result -ErrorAction SilentlyContinue $FilteredApps = @() if ($is_iPhone) { $FilteredApps += $AppInfo | Where-Object {$_.Platforms -eq "iPhone" } } if ($is_iPad) { $FilteredApps += $AppInfo | Where-Object {$_.Platforms -eq "iPad" } } if ($is_Mac) { $FilteredApps += $AppInfo | Where-Object {$_.Platforms -eq "Mac" } } if ($is_Watch) { $FilteredApps += $AppInfo | Where-Object {$_.Platforms -eq "Watch" } } if ($is_AppleTV) { $FilteredApps += $AppInfo | Where-Object {$_.Platforms -eq "AppleTV" } } $AppInfo = $FilteredApps | Sort-Object -Property AppID -Unique | Sort-Object -Property AppName Write-Output ($AppInfo) $is_Finished = $ttrue } $is_NoFiltered = $true if ($false -eq $is_Finished) { Write-Verbose ("Normal mode") if ($Developer) { $FilterDeveloper=$Term $is_NoFiltered = $false } if ($is_iPhone) { Write-Verbose ("iPhone mode") if ($Developer) { $URL = ('{0}term={1}&country={2}&entity=allArtist&attribute=softwareDeveloper&limit=200' -f $iTunesSearchURL, ($Term.Replace(" ","+")), $Country) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Result = @($SearchResult.Results | Where-Object {$_.artistType -eq "Software Artist"}) switch ($FilterMode) { "None" { $Result = $Result } "Equal" { $Result = $Result | Where-Object {$_.artistName -eq ("{0}" -f $FilterDeveloper)} } "Like" { $Result = $Result | Where-Object {$_.artistName -like ("*{0}*" -f $FilterDeveloper)} } } foreach ($D in $Result.artistID) { $AppInfo += Get-iTunesAppInfo -Term $D -Platform iPhone -DeveloperID -Country $Country -ErrorAction SilentlyContinue } } else { $Result = Search-iTunesStoreApp -Entity software -Term $Term -Country $Country if ($is_NoFiltered) { switch ($FilterMode) { "None" { $Result = $Result } "Equal" { $Result = $Result | Where-Object {$_.trackName -eq ("{0}" -f $Term)} } "Like" { $Result = $Result | Where-Object {$_.trackName -like ("*{0}*" -f $Term)} } } } if ($null -ne $Result) { $AppInfo += Summary-AppInfo -Results $Result -ErrorAction SilentlyContinue } } } if ($is_iPad) { Write-Verbose ("iPad mode") if ($Developer) { $URL = ('{0}term={1}&country={2}&entity=allArtist&attribute=softwareDeveloper&limit=200' -f $iTunesSearchURL, ($Term.Replace(" ","+")), $Country) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Result = @($SearchResult.Results | Where-Object {$_.artistType -eq "Software Artist"}) switch ($FilterMode) { "None" { $Result = $Result } "Equal" { $Result = $Result | Where-Object {$_.artistName -eq ("{0}" -f $FilterDeveloper)} } "Like" { $Result = $Result | Where-Object {$_.artistName -like ("*{0}*" -f $FilterDeveloper)} } } foreach ($D in $Result.artistID) { $AppInfo += Get-iTunesAppInfo -Term $D -Platform iPad -DeveloperID -Country $Country -ErrorAction SilentlyContinue } } else { $Result = Search-iTunesStoreApp -Entity iPadSoftware -Term $Term -Country $Country if ($is_NoFiltered) { switch ($FilterMode) { "None" { $Result = $Result } "Equal" { $Result = $Result | Where-Object {$_.trackName -eq ("{0}" -f $Term)} } "Like" { $Result = $Result | Where-Object {$_.trackName -like ("*{0}*" -f $Term)} } } } if ($null -ne $Result) { $AppInfo += Summary-AppInfo -Results $Result -ErrorAction SilentlyContinue } } } if ($is_Mac) { Write-Verbose ("Mac mode") if ($Developer) { $URL = ('{0}term={1}&country={2}&entity=allArtist&attribute=softwareDeveloper&limit=200' -f $iTunesSearchURL, ($Term.Replace(" ","+")), $Country) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Result = @($SearchResult.Results | Where-Object {$_.artistType -eq "Software Artist"}) switch ($FilterMode) { "None" { $Result = $Result } "Equal" { $Result = $Result | Where-Object {$_.artistName -eq ("{0}" -f $FilterDeveloper)} } "Like" { $Result = $Result | Where-Object {$_.artistName -like ("*{0}*" -f $FilterDeveloper)} } } foreach ($D in $Result.artistID) { $AppInfo += Get-iTunesAppInfo -Term $D -Platform Mac -DeveloperID -Country $Country -ErrorAction SilentlyContinue } } else { $Result = Search-iTunesStoreApp -Entity macSoftware -Term $Term -Country $Country if ($is_NoFiltered) { switch ($FilterMode) { "None" { $Result = $Result } "Equal" { $Result = $Result | Where-Object {$_.trackName -eq ("{0}" -f $Term)} } "Like" { $Result = $Result | Where-Object {$_.trackName -like ("*{0}*" -f $Term)} } } } if ($null -ne $Result) { $AppInfo += Summary-AppInfo -Results $Result -ErrorAction SilentlyContinue } } } if ($is_Watch) { Write-Verbose ("Watch mode") if ($Developer) { $URL = ('{0}term={1}&country={2}&entity=allArtist&attribute=softwareDeveloper&limit=200' -f $iTunesSearchURL, ($Term.Replace(" ","+")), $Country) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Result = @($SearchResult.Results | Where-Object {$_.artistType -eq "Software Artist"}) switch ($FilterMode) { "None" { $Result = $Result } "Equal" { $Result = $Result | Where-Object {$_.artistName -eq ("{0}" -f $FilterDeveloper)} } "Like" { $Result = $Result | Where-Object {$_.artistName -like ("*{0}*" -f $FilterDeveloper)} } } foreach ($D in $Result.artistID) { $AppInfo += Get-iTunesAppInfo -Term $D -Platform Watch -DeveloperID -Country $Country -ErrorAction SilentlyContinue } } else { $Result = Search-iTunesStoreApp -Entity watchSoftware -Term $Term -Country $Country if ($is_NoFiltered) { switch ($FilterMode) { "None" { $Result = $Result } "Equal" { $Result = $Result | Where-Object {$_.trackName -eq ("{0}" -f $Term)} } "Like" { $Result = $Result | Where-Object {$_.trackName -like ("*{0}*" -f $Term)} } } } if ($null -ne $Result) { $AppInfo += Summary-AppInfo -Results $Result -ErrorAction SilentlyContinue } } } if ($is_AppleTV) { Write-Verbose ("AppleTV mode") if ($Developer) { $URL = ('{0}term={1}&country={2}&entity=allArtist&attribute=softwareDeveloper&limit=200' -f $iTunesSearchURL, ($Term.Replace(" ","+")), $Country) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Result = @($SearchResult.Results | Where-Object {$_.artistType -eq "Software Artist"}) switch ($FilterMode) { "None" { $Result = $Result } "Equal" { $Result = $Result | Where-Object {$_.artistName -eq ("{0}" -f $FilterDeveloper)} } "Like" { $Result = $Result | Where-Object {$_.artistName -like ("*{0}*" -f $FilterDeveloper)} } } foreach ($D in $Result.artistID) { $AppInfo += Get-iTunesAppInfo -Term $D -Platform Watch -DeveloperID -Country $Country -ErrorAction SilentlyContinue } } else { $Result = Search-iTunesStoreApp -Entity tvSoftware -Term $Term -Country $Country if ($is_NoFiltered) { switch ($FilterMode) { "None" { $Result = $Result } "Equal" { $Result = $Result | Where-Object {$_.trackName -eq ("{0}" -f $Term)} } "Like" { $Result = $Result | Where-Object {$_.trackName -like ("*{0}*" -f $Term)} } } } if ($null -ne $Result) { $AppInfo += Summary-AppInfo -Results $Result -ErrorAction SilentlyContinue } } } $AppInfo = $AppInfo | Sort-Object -Property AppID -Unique | Where-Object -Property AppName Write-Output ($AppInfo) } } function Search-iTunesStoreApp { param( [Parameter(Mandatory=$false,Position=1)] [ValidateSet("software","iPadSoftware","macSoftware","watchSoftware","tvSoftware")] [String]$Entity="software", [Parameter(Mandatory=$true,Position=2)] [String]$Term, [Parameter(Mandatory=$false,Position=3)] [String]$Country="jp" ) $iTunesSearchURL ="https://itunes.apple.com/search?" $WebClient = New-Object System.Net.WebClient $WebClient.Encoding = [System.Text.Encoding]::UTF8 $offset=0 $Result = @() $All = $false While ($false -eq $All) { $URL = ('{0}term={1}&country={2}&entity={3}&limit=200&offset={4}' -f $iTunesSearchURL, ($Term.Replace(" ","+")), $Country,$Entity,$offset) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Work = @($SearchResult.Results) $Result += $Work if ($Work.Count -ge 200) {$offset += 200;Write-Verbose ("`tOffset Loop:{0}" -f $offset); } else { $All = $true} } $Result = $Result | Sort-Object -Property TrackID -Unique Write-Output @($Result) } function Summary-AppInfo { param( [Parameter(Mandatory=$true,Position=1)] [Array]$Results ) $AppInfo = @() foreach ($R in $Results) { $Mem = New-Object PSObject $Mem | Add-Member -MemberType NoteProperty -Name AppName -Value $R.trackName $Mem | Add-Member -MemberType NoteProperty -Name Version -Value $R.version $Mem | Add-Member -MemberType NoteProperty -Name AppID -Value $R.trackID $Mem | Add-Member -MemberType NoteProperty -Name BundleID -Value $R.bundleID $Mem | Add-Member -MemberType NoteProperty -Name ArtistName -Value $R.artistName $Mem | Add-Member -MemberType NoteProperty -Name SellerName -Value $R.sellerName $Mem | Add-Member -MemberType NoteProperty -Name Description -Value $R $Platforms = @() $Work = @($R.SupportedDevices | Where-Object { $_ -like "iPhone*"}) if ($Work.Count -ne 0) { $Platforms += "iPhone" } $Work = @($R.SupportedDevices | Where-Object { $_ -like "iPad*"}) if ($Work.Count -ne 0) { $Platforms += "iPad" } $Work = @($R.SupportedDevices | Where-Object { $_ -like "Mac*"}) if ($Work.Count -ne 0) { $Platforms += "Mac" } if ($R.kind -eq "mac-software") { $Platforms += "Mac" } $Work = @($R.SupportedDevices | Where-Object { $_ -like "Watch*"}) if ($Work.Count -ne 0) { $Platforms += "Watch" } $Work = @($R.SupportedDevices | Where-Object { $_ -like "AppleTV*"}) if ($Work.Count -ne 0) { $Platforms += "AppleTV" } $Platforms = @($Platforms | Sort-Object -Unique) $Mem | Add-Member -MemberType NoteProperty -Name Platforms -Value $Platforms $defaultProperties = @("AppName","AppID","BundleID","ArtistName") $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet("DefaultDisplayPropertySet",[string[]]$defaultProperties) $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) $Mem | Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers $AppInfo += $Mem } Write-Output $AppInfo } # # Get-iTunesArtistInfo # function Get-iTunesArtistInfo { <# .SYNOPSIS iTunes Store の Artist 情報を検索します。 .DESCRIPTION iTunes Store の Artist 情報を検索します。 .EXAMPLE Get-iTunesArtistInfo -Term 広島綾子 アーティスト名で検索する場合 .EXAMPLE Get-iTunesArtistInfo -Teem "広島*綾子" アーティスト名の姓名のは間に半角スペースの有無など不明な場合、ワイルドカードの "*" を指定します。 .EXAMPLE Get-iTunesArtistInfo -Term Apple -ArtistType SoftwareArtist -FilterMode Equal "Apple" というソフトウェア開発者を探す場合。 Term に "Apple" と指定し、ArtistType オプションで "SoftwareArtist" を指定して種別を限定します。 且つ、FilterMode オプションに "Equal" を指定し、Term と同じ文字列を持つものだけにフィルタします。 Term に "Apple" のみの場合、"Apple" を ArtistName に含むすべてのアーティストが検索結果に含まれ、 名前が "Apple Bank" など "Apple" ではないものや音楽系のアーティストも含まれてしまいます。 .PARAMETER Term 検索するキーワードを指定します。スペースを含む場合は "TM Network" の様にします。 .PARAMETER Search 検索するあ0ティスとカテゴリを指定します。 musicArtist、movieArtist、shorFilmArtist、allArtist から選択します。 ソフトウェア開発者を検索したい場合は AllArtist を指定してください。 デフォルト値は "allArtist" です。 App 開発元を検索したい場合は "allArtist" を指定してください。 それによって「Software Artist」種別がヒットするようになります。 .PARAMETER ArtistType 結果リストとして必要とするアーティスト種別を指定します。 を指定します。 All、Artist、SoftwareArtist、PodcastArtist、MovieArtist から選択します。 デフォルト値は AllArtist です。 .PARAMETER Country AppSotre の国コードを指定します。デフォルト値は "jp" です。 .PARAMETER ArtiestID Artist の URL などから ID 情報が判明している場合、ID を指定して検索することができます。 .PARAMETER FilterMode Term に指定したキーワードが ArtistName に含まれる度合いを指定します。 None、Like、Equal から指定します。 規定値は "Like" です。 "None" を指定した場合、iTunes 検索結果のリストをそのまま出力として使用します。 ArtistName に指定した Term が直接的に含まれていないものが結果に含まれる可能性があります。 "Like" を指定した場合、iTunes 検索検索結果の ArtistName に Term 文字列が含まれるもののみをフィルタして返します。 意図した検索結果が見つかりやすくなります。 "Equal" を指定した場合、iTunes 検索結果のリストから ArtistName が Term 文字列と同じもののみをフィルタして返します。 検索対象のフルネームなどを知っている場合に検索結果を見つけやすくなる場合があります。 .LINK .NOTES .INPUTS パイプラインからの入力可能です。 .OUTPUTS 文字列 #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification="Always multiple results.")] param( [Parameter(Mandatory=$True,Position=1)] [String]$Term, [Parameter(Mandatory=$false,Position=2)] [ValidateSet("mixTerm","genreIndex","artistTerm","composerTerm","albumTerm","raitingIndex","songTerm","producerTerm")] [String]$TermType="mixTerm", [Parameter(Mandatory=$false,Position=3)] [ValidateSet("movieArtist","musicArtist","shortFilmArtist","allArtist")] [String]$Search="allArtist", [Parameter(Mandatory=$false,Position=4)] [ValidateSet("All","Artist","SoftwareArtist","PodcastArtist","MovieArtist")] [String]$ArtistType="All", [Parameter(Mandatory=$false,Position=5)] [String]$Country="jp", [Parameter(Mandatory=$false,Position=6)] [Switch]$ArtistID=$false, [Parameter(Mandatory=$false,Position=7)] [ValidateSet("None","Like","Equal")] [String]$FilterMode="None" ) $iTunesSearchURL ="https://itunes.apple.com/search?" $iTunesLookupURL ="https://itunes.apple.com/lookup?" $WebClient = New-Object System.Net.WebClient $WebClient.Encoding = [System.Text.Encoding]::UTF8 Write-Verbose ("Term = '{0}', Search = {1}, ArtistType = {2}, Country = {3}, ArtistID : {4}, FilterMode : {4}, TermType : {5}" -f $Term, $Search, $ArtistType, $Country, $ArtistID, $FilterMode, $TermType) $ArtistInfo = @() if ($ArtistId) { $URL = ('{0}id={1}&country={2}' -f $iTunesLookupURL, $Term, $Country) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Result = @($SearchResult.Results) if ($null -ne $Result) { $ArtistInfo += Summary-ArtistInfo -Results $Result } } else { $URL = ('{0}term={1}&country={2}&entity={3}&limit=200&attribute={4}' -f $iTunesSearchURL, ($Term.Replace(" ","+")), $Country, $Search,$TermType) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Result = @($SearchResult.Results) switch ($ArtistType) { "All" { $Result = $Result } "Artist" { $Result = $Result | Where-Object {$_.artistType -eq "Artist"} } "SoftwareArtist" { $Result = $Result | Where-Object {$_.artistType -eq "Software Artist"} } "PodcastArtist" { $Result = $Result | Where-Object {$_.artistType -eq "Podcast Artist"} } "MovieArtist" { $Result = $Result | Where-Object {$_.artistType -eq "Movie Artist"} } } switch ($FilterMode) { "None" { $Result = $Result } "Like" { $Result = $Result | Where-Object {$_.artistName -like ("*{0}*" -f $Term)} } "Equal" { $Result = $Result | Where-Object {$_.artistName -eq ("{0}" -f $Term)} } } if ($null -ne $Result) { $ArtistInfo += Summary-ArtistInfo -Results $Result } } $ArtistInfo = $ArtistInfo | Sort-Object -Property ArtistName Write-Output ($ArtistInfo) } function Summary-ArtistInfo { param( [Parameter(Mandatory=$true,Position=1)] [Array]$Results ) $ArtistInfo = @() foreach ($R in $Results) { $Mem = New-Object PSObject $Mem | Add-Member -MemberType NoteProperty -Name ArtistName -Value $R.ArtistName $Mem | Add-Member -MemberType NoteProperty -Name ArtistType -Value $R.ArtistType $Mem | Add-Member -MemberType NoteProperty -Name ArtistID -Value $R.ArtistID $Mem | Add-Member -MemberType NoteProperty -Name PrimaryGenreName -Value $R.PrimaryGenreName $Mem | Add-Member -MemberType NoteProperty -Name LinkURL -Value $R.ArtistLinkUrl $Mem | Add-Member -MemberType NoteProperty -Name Description -Value $R $defaultProperties = @("ArtistName","ArtistType","ArtistID","PrimaryGenreName") $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet("DefaultDisplayPropertySet",[string[]]$defaultProperties) $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) $Mem | Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers $ArtistInfo += $Mem } Write-Output $ArtistInfo } # # Get-iTunesMusicInfo # function Get-iTunesMusicInfo { <# .SYNOPSIS iTunes Store の楽曲情報を検索します。 .DESCRIPTION iTunes Store の楽曲情報を検索します。 .EXAMPLE Get-iTunesMusicInfo -Term 広島綾子 -Artist -WhatIs Album アーティスト「広島綾子」のアルバムを表示します。 .PARAMETER Term 検索するキーワードを指定します。スペースを含む場合は "Microsoft Word" の様にします。 .PARAMETER TermType 検索キーワードの種類を指定します。 mixTerm = デフォルト値。複合。 genreIndex = ジャンルを指定 artistTerm = アーティスト名を指定 composerTerm = コンポーザーを指定 albumTerm = アルバムを指定 raitingIndex = レートを指定 songTerm = 曲名を指定 producerTerm = プロデューサーを指定 .PARAMETER WhatIs 検索対象を指定します。 musicTrack = musicTrack が対象になります。 album = アルバムが対象になります。 musicVideo = ミュージックビデオ が対象になります。 mix = 複合。 song = デフォルト値。歌が対象になります。 .PARAMETER Country AppSotre の国コードを指定します。デフォルト値は "jp" です。 .PARAMETER SongID 楽曲の URL などから ID 情報が判明している場合、ID を指定して検索することができます。 .PARAMETER AlbumID アルバムの URL などから ID 情報が判明している場合、ID を指定して検索することができます。 .PARAMETER Artist Term に指定したキーワードがアーティスト名である場合、このオプションを指定することでよりある程度フィルタして結果を出すことができます。 .PARAMETER ArtistID アーティストの URL などから ID 情報が判明している場合、ID を指定して検索することができます。 .PARAMETER FilterMode Term に指定したキーワードが ArtistName に含まれる度合いを指定します。 None、Like、Equal から指定します。 規定値は "None" です。 "None" を指定した場合、iTunes 検索結果のリストをそのまま出力として使用します。 ArtistName に指定した Term が直接的に含まれていないものが結果に含まれる可能性があります。 "Like" を指定した場合、iTunes 検索検索結果に Term 文字列が含まれるもののみをフィルタして返します。 意図した検索結果が見つかりやすくなります。 "Equal" を指定した場合、iTunes 検索結果のリストから Term 文字列と同じもののみをフィルタして返します。 検索対象の登録名称などを知っている場合に検索結果を見つけやすくなる場合があります。 .LINK .NOTES .INPUTS パイプラインからの入力可能です。 .OUTPUTS 文字列 #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification="Always multiple results.")] param( [Parameter(Mandatory=$True,Position=1)] [String]$Term, [Parameter(Mandatory=$false,Position=2)] [ValidateSet("mixTerm","genreIndex","artistTerm","composerTerm","albumTerm","raitingIndex","songTerm","producerTerm")] [String]$TermType="mixTerm", [Parameter(Mandatory=$false,Position=3)] [ValidateSet("musicTrack","album","musicVideo","mix","song")] [String]$WhatIs="song", [Parameter(Mandatory=$false,Position=4)] [String]$Country="jp", [Parameter(Mandatory=$false,Position=5)] [Switch]$SongID=$false, [Parameter(Mandatory=$false,Position=6)] [Switch]$AlbumID=$false, [Parameter(Mandatory=$false,Position=7)] [Switch]$Artist=$false, [Parameter(Mandatory=$false,Position=8)] [Switch]$ArtistID=$false, [Parameter(Mandatory=$false,Position=9)] [ValidateSet("None","Like","Equal")] [String]$FilterMode="None" ) $iTunesSearchURL ="https://itunes.apple.com/search?" $iTunesLookupURL ="https://itunes.apple.com/lookup?" $WebClient = New-Object System.Net.WebClient $WebClient.Encoding = [System.Text.Encoding]::UTF8 Write-Verbose ("Term = '{0}', TermType = '{1}', WhatIs = {2}, Country = {3}, SongID : {4}, AlbumID : {5}, Artist : {6}, ArtistID : {7}, FilterMode : {8}" -f $Term, $TermType, $WhatIs, $Country, $SongID, $AlbumID, $Artist, $ArtistID, $FilterMode) $MusicInfo = @() $is_Finished = $false if ($SongID) { $URL = ('{0}id={1}&country={2}' -f $iTunesLookupURL, $Term, $Country) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Result = @($SearchResult.Results) if ($null -ne $Result) { $MusicInfo += Summary-MusicInfo -Results $Result } $is_Finished = $True } if ($AlbumId) { $offset=0 $Result = @() $All = $false While ($false -eq $All) { $URL = ('{0}id={1}&country={2}&offset={3}&entity={4}&limit=200' -f $iTunesLookupURL, $Term, $Country,$offset,$WhatIs) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Work = @($SearchResult.Results) $Result += $Work if ($Work.Count -ge 200) {$offset += 200;Write-Verbose ("`tOffset Loop:{0}" -f $offset); } else { $All = $true} } if ($null -ne $Result) { $MusicInfo += Summary-MusicInfo -Results $Result } $is_Finished = $True } if ($ArtistId) { Write-Verbose ("ArtistID") $offset=0 $Result = @() $All = $false While ($false -eq $All) { $URL = ('{0}id={1}&country={2}&limit=200&offset={3}&entity={4}' -f $iTunesLookupURL, $Term, $Country,$offset,$WhatIs) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Work = @($SearchResult.Results) $Result += $Work if ($Work.Count -ge 200) {$offset += 200;Write-Verbose ("`tOffset Loop:{0}" -f $offset); } else { $All = $true} $All = $true } if ($null -ne $Result) { $MusicInfo += Summary-MusicInfo -Results $Result } $is_Finished = $True } if ($false -eq $is_Finished) { if ($Artist) { $FilterArtist=$Term } if ($Artist) { $URL = ('{0}term={1}&country={2}&entity=musicArtist&attribute=artistTerm&limit=200' -f $iTunesSearchURL, ($Term.Replace(" ","+")), $Country) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Result = @($SearchResult.Results | Where-Object {$_.artistType -ne "Software Artist"}) switch ($FilterMode) { "None" { $Result = $Result } "Equal" { $Result = $Result | Where-Object {$_.artistName -eq ("{0}" -f $FilterArtist)} } "Like" { $Result = $Result | Where-Object {$_.artistName -like ("*{0}*" -f $FilterArtist)} } } foreach ($A in $Result.artistID) { $MusicInfo += Get-iTunesMusicInfo -Term $A -WhatIs $WhatIs -ArtistID -Country $Country -ErrorAction SilentlyContinue } } else { $offset=0 $Result = @() $All = $false While ($false -eq $All) { $URL = ('{0}term={1}&country={2}&entity={3}&attribute={4}&limit=200&offset={5}' -f $iTunesSearchURL, ($Term.Replace(" ","+")), $Country, $WhatIs, $TermType,$offset) $SearchResult = ConvertFrom-Json $WebClient.DownloadString($URL) $Work = @($SearchResult.Results) $Result += $Work if ($Work.Count -ge 200) {$offset += 200;Write-Verbose ("`tOffset Loop:{0}" -f $offset); } else { $All = $true} } switch ($FilterMode) { "None" { $Result = $Result } "Like" { switch ($TermType) { "producerTerm" { $Result = $Result | Where-Object {$_.artistName -like ("*{0}*" -f $Term)} } "composerTerm" { $Result = $Result | Where-Object {$_.artistName -like ("*{0}*" -f $Term)} } "artistTerm" { $Result = $Result | Where-Object {$_.artistName -like ("*{0}*" -f $Term)} } "genreIndex" { $Result = $Result | Where-Object {$_.primaryGenreName -like ("*{0}*" -f $Term)} } "albumTerm" { $Result = $Result | Where-Object {$_.collectionName -like ("*{0}*" -f $Term)} } default { $Result = $Result | Where-Object {$_.trackName -like ("*{0}*" -f $Term)} } } } "Equal" { switch ($TermType) { "producerTerm" { $Result = $Result | Where-Object {$_.artistName -eq ("{0}" -f $Term)} } "composerTerm" { $Result = $Result | Where-Object {$_.artistName -eq ("{0}" -f $Term)} } "artistTerm" { $Result = $Result | Where-Object {$_.artistName -eq ("{0}" -f $Term)} } "genreIndex" { $Result = $Result | Where-Object {$_.primaryGenreName -eq ("{0}" -f $Term)} } "albumTerm" { $Result = $Result | Where-Object {$_.collectionName -eq ("{0}" -f $Term)} } default { $Result = $Result | Where-Object {$_.trackName -eq ("{0}" -f $Term)} } } } } if ($null -ne $Result) { $MusicInfo += Summary-MusicInfo -Results $Result } } } switch ($WhatIs) { "album" { $MusicInfo = $MusicInfo | Where-Object {$_.Description.wrapperType -ne "artist" } | Sort-Object -Property AlbumID -Unique | Sort-Object -Property ArtistName,AlbumName,Disc-Track,MusicName } default { $MusicInfo = $MusicInfo | Where-Object {$_.Description.wrapperType -ne "artist" } | Sort-Object -Property MusicID -Unique | Sort-Object -Property ArtistName,AlbumName,Disc-Track,MusicName } } Write-Output ($MusicInfo) } function Summary-MusicInfo { param( [Parameter(Mandatory=$true,Position=1)] [Array]$Results ) $MusicInfo = @() foreach ($R in $Results) { switch ($R.wrapperType) { "collection" { $Mem = New-Object PSObject $Mem | Add-Member -MemberType NoteProperty -Name AlbumName -Value $R.collectionName $Mem | Add-Member -MemberType NoteProperty -Name AlbumID -Value $R.collectionID $Mem | Add-Member -MemberType NoteProperty -Name AlbumURL -Value $R.collectionViewURL $Mem | Add-Member -MemberType NoteProperty -Name ArtistName -Value $R.artistName $Mem | Add-Member -MemberType NoteProperty -Name ArtistID -Value $R.ArtistID $Mem | Add-Member -MemberType NoteProperty -Name ArtistURL -Value $R.artistViewURL $Mem | Add-Member -MemberType NoteProperty -Name Tracks -Value $this.TrackCount $Mem | Add-Member -MemberType NoteProperty -Name ReleaseDate -Value $R.releaseDate $Mem | Add-Member -MemberType NoteProperty -Name Description -Value $R $defaultProperties = @("AlbumName","ArtistName","Tracks","ReleaseDate") $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet("DefaultDisplayPropertySet",[string[]]$defaultProperties) $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) $Mem | Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers } default { $Mem = New-Object PSObject $Mem | Add-Member -MemberType NoteProperty -Name MusicName -Value $R.trackName $Mem | Add-Member -MemberType NoteProperty -Name MusicID -Value $R.trackID $Mem | Add-Member -MemberType NoteProperty -Name MusicURL -Value $R.trackViewURL $Mem | Add-Member -MemberType NoteProperty -Name AlbumName -Value $R.collectionName $Mem | Add-Member -MemberType NoteProperty -Name AlbumID -Value $R.collectionID $Mem | Add-Member -MemberType NoteProperty -Name AlbumURL -Value $R.collectionViewURL $Mem | Add-Member -MemberType NoteProperty -Name ArtistName -Value $R.artistName $Mem | Add-Member -MemberType NoteProperty -Name ArtistID -Value $R.ArtistID $Mem | Add-Member -MemberType NoteProperty -Name ArtistURL -Value $R.artistViewURL $Mem | Add-Member -MemberType NoteProperty -Name DiscCount -Value $R.DiscCount $Mem | Add-Member -MemberType NoteProperty -Name DiscNumber -Value $R.DiscNumber $Mem | Add-Member -MemberType NoteProperty -Name TrackCount -Value $R.TrackCount $Mem | Add-Member -MemberType NoteProperty -Name TrackNumber -Value $R.TrackNumber $Mem | Add-Member -MemberType ScriptProperty -Name Disc-Track -Value { ("{0:00}/{1:00}-{2:00}/{3:00}" -f $this.DiscNumber, $this.DiscCount, $this.TrackNumber, $this.TrackCount) } $Mem | Add-Member -MemberType NoteProperty -Name ReleaseDate -Value $R.releaseDate $Mem | Add-Member -MemberType NoteProperty -Name Description -Value $R $defaultProperties = @("Disc-Track","AlbumName","MusicName","ArtistName") $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet("DefaultDisplayPropertySet",[string[]]$defaultProperties) $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) $Mem | Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers } } $MusicInfo += $Mem } Write-Output $MusicInfo } function Get-Wild { <# .SYNOPSIS iTunes Store の楽曲情報から「Get Wild」を検索します。 .DESCRIPTION iTunes Store の楽曲情報から「Get Wild」を検索します。 内部的に Get-iTunesMusicInfo コマンドの結果を利用しています。 .EXAMPLE Get-Wild アルバム別にソートしたサマリが表示されます。 .EXAMPLE Get-Wild -sortArtist -withURL アーティスト順にソートしたサマリが表示されます。 また、各曲の iTunes URL が含まれます。 .PARAMETER List 整形前のデータオブジェクト配列を返します。 .PARAMETER sortArtist アーティスト順にソートします。 .PARAMETER withURL 各曲の iTunes URL を含んだ表示をします。 .PARAMETER Country AppSotre の国コードを指定します。デフォルト値は "jp" です。 .LINK .NOTES .INPUTS パイプラインからの入力不可です。 .OUTPUTS 文字列 #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification="Always multiple results.")] param( [Parameter(Mandatory=$false,Position=1)] [Switch]$List, [Parameter(Mandatory=$false,Position=2)] [Switch]$withURL, [Parameter(Mandatory=$false,Position=3)] [Switch]$SortArtist, [Parameter(Mandatory=$false,Position=4)] [String]$Country="jp" ) $ArtistNameFormat =-20 $AlbumNameFormat =-45 $MusicNameFormat =-45 $DiscTrackFormat =-11 $ArtistNameLimit =15 $AlbumNameLimit =35 $MusicNameLimit =35 $MusicInfo = Get-iTunesMusicInfo -Term "Get Wild" -TermType songTerm -FilterMode Like -Country $Country if ($True -eq $SortArtist) { $MusicInfo = $MusicInfo | Sort-Object -Property ArtistName, AlbumName, Disc-Track } else { $MusicInfo = $MusicInfo | Sort-Object -Property AlbumName, Disc-Track } if ($True -eq $List) { Write-Output $MusicInfo } else { Write-Output ("Search iTunes Music ({0})`n" -f $Country) if ($True -eq $SortArtist) { $Artists = $MusicInfo | Group-Object -Property ArtistName foreach ($Artist in $Artists) { Write-Output ("Artist Name: {0}`n" -f $Artist.Name) $Tracks = $Artist.Group | Sort-Object -Property AlbumName, Disc-Track, MusicName Write-Output (" {0,$AlbumNameFormat} {1,$DiscTrackFormat} {2,$MusicNameFormat}" -f "Album Name","Disc-Track","Music Name") foreach ($Track in $Tracks) { $MusicNameNumOf = 0 $ArtistNameNumOf = 0 $AlbumNameNumOf = 0 $MusicNameWork = $Track.MusicName.Split(" ") $ArtistNameWork = $Track.ArtistName.Split(" ") $AlbumNameWork = $Track.AlbumName.Split(" ") $MaxWords = [math]::Max($MusicNameWork.Count,[math]::Max($ArtistNameWork.Count,$AlbumNameWork.Count)) $MusicNameBuild = @() $ArtistNameBuild = @() $AlbumNameBuild = @() $MusicNameRebuild ="" $ArtistNameRebuild ="" $AlbumNameRebuild ="" for ($i=0; $i -lt $MaxWords; $i++) { $MusicNameRebuild += (" {0}" -f $MusicNameWork[$i]) if ($MusicNameLimit -le $MusicNameRebuild.Length) { $MusicNameBuild += $MusicNameRebuild.Trim() $MusicNameRebuild = "" $MusicNameNumOf++ } $ArtistNameRebuild += ("{0} " -f $ArtistNameWork[$i]) if ($ArtistNameLimit -le $ArtistNameRebuild.Length) { $ArtistNameBuild += $ArtistNameRebuild.Trim() $ArtistNameRebuild = "" $ArtistNameNumOf++ } $AlbumNameRebuild += ("{0} " -f $AlbumNameWork[$i]) if ($AlbumNameLimit -le $AlbumNameRebuild.Length) { $AlbumNameBuild += $AlbumNameRebuild.Trim() $AlbumNameRebuild = "" $AlbumNameNumOf++ } } if (($MusicNameRebuild.Trim()).Length -ne 0) { $MusicNameBuild += $MusicNameRebuild.Trim() $MusicNameRebuild = "" $MusicNameNumOf++ } if (($ArtistNameRebuild.Trim()).Length -ne 0) { $ArtistNameBuild += $ArtistNameRebuild.Trim() $ArtistNameRebuild = "" $ArtistNameNumOf++ } if (($AlbumNameRebuild.Trim()).Length -ne 0) { $AlbumNameBuild += $AlbumNameRebuild.Trim() $AlbumNameRebuild = "" $AlbumNameNumOf++ } $DiscTrack = @( $Track."Disc-Track") $MaxWords = [math]::Max($MusicNameNumof,$AlbumNameNumof) for ($i=0; $i -lt $MaxWords;$i++) { Write-Output (" {0,$AlbumNameFormat} {1,$DiscTrackFormat} {2,$MusicNameFormat}" -f $AlbumNameBuild[$i],$DiscTrack[$i],$MusicNameBuild[$i]) } if ($True -eq $withURL) { Write-Output ($Track.musicURL) } } Write-Output ("") } } else { $Albums = $MusicInfo | Group-Object -Property AlbumName foreach ($Album in $Albums) { Write-Output ("Album Name: {0}`n" -f $Album.Name) $Tracks = $Album.Group | Sort-Object -Property Disc-Track Write-Output (" {0,$DiscTrackFormat} {1,$MusicNameFormat} {2,$ArtistNameFormat}" -f "Disc-Track","Music Name","Artist Name") foreach ($Track in $Tracks) { $MusicNameNumOf = 0 $ArtistNameNumOf = 0 $AlbumNameNumOf = 0 $MusicNameWork = $Track.MusicName.Split(" ") $ArtistNameWork = $Track.ArtistName.Split(" ") $AlbumNameWork = $Track.AlbumName.Split(" ") $MaxWords = [math]::Max($MusicNameWork.Count,[math]::Max($ArtistNameWork.Count,$AlbumNameWork.Count)) $MusicNameBuild = @() $ArtistNameBuild = @() $AlbumNameBuild = @() $MusicNameRebuild ="" $ArtistNameRebuild ="" $AlbumNameRebuild ="" for ($i=0; $i -lt $MaxWords; $i++) { $MusicNameRebuild += (" {0}" -f $MusicNameWork[$i]) if ($MusicNameLimit -le $MusicNameRebuild.Length) { $MusicNameBuild += $MusicNameRebuild.Trim() $MusicNameRebuild = "" $MusicNameNumOf++ } $ArtistNameRebuild += ("{0} " -f $ArtistNameWork[$i]) if ($ArtistNameLimit -le $ArtistNameRebuild.Length) { $ArtistNameBuild += $ArtistNameRebuild.Trim() $ArtistNameRebuild = "" $ArtistNameNumOf++ } $AlbumNameRebuild += ("{0} " -f $AlbumNameWork[$i]) if ($AlbumNameLimit -le $AlbumNameRebuild.Length) { $AlbumNameBuild += $AlbumNameRebuild.Trim() $AlbumNameRebuild = "" $AlbumNameNumOf++ } } if (($MusicNameRebuild.Trim()).Length -ne 0) { $MusicNameBuild += $MusicNameRebuild.Trim() $MusicNameRebuild = "" $MusicNameNumOf++ } if (($ArtistNameRebuild.Trim()).Length -ne 0) { $ArtistNameBuild += $ArtistNameRebuild.Trim() $ArtistNameRebuild = "" $ArtistNameNumOf++ } if (($AlbumNameRebuild.Trim()).Length -ne 0) { $AlbumNameBuild += $AlbumNameRebuild.Trim() $AlbumNameRebuild = "" $AlbumNameNumOf++ } $DiscTrack = @( $Track."Disc-Track") $MaxWords = [math]::Max($MusicNameNumof,$ArtistNameNumof) for ($i=0; $i -lt $MaxWords;$i++) { Write-Output (" {0,$DiscTrackFormat} {1,$MusicNameFormat} {2,$ArtistNameFormat}" -f $DiscTrack[$i], $MusicNameBuild[$i], $ArtistNameBuild[$i]) } if ($True -eq $withURL) { Write-Output ($Track.musicURL) } } Write-Output ("") } } } } Export-ModuleMember -Function Get-iTunesAppInfo, Get-itunesArtistInfo, Get-iTunesMusicInfo, Get-Wild |